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

#include "DispatchTables.h"
#include "NativeSubWindow.h"
#include "RenderThreadInfo.h"
#include "gles2_dec.h"

#include "OpenGLESDispatch/EGLDispatch.h"

#include "android/base/system/System.h"
#include "emugl/common/logging.h"

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

namespace {

// Helper class to call the bind_locked() / unbind_locked() properly.
class ScopedBind {
public:
    // Constructor will call bind_locked() on |fb|.
    // Use isValid() to check for errors.
    ScopedBind(FrameBuffer* fb) : mFb(fb) {
        if (!mFb->bind_locked()) {
            mFb = NULL;
        }
    }

    // Returns true if contruction bound the framebuffer context properly.
    bool isValid() const { return mFb != NULL; }

    // Unbound the framebuffer explictly. This is also called by the
    // destructor.
    void release() {
        if (mFb) {
            mFb->unbind_locked();
            mFb = NULL;
        }
    }

    // Destructor will call release().
    ~ScopedBind() {
        release();
    }

private:
    FrameBuffer* mFb;
};

// Implementation of a ColorBuffer::Helper instance that redirects calls
// to a FrameBuffer instance.
class ColorBufferHelper : public ColorBuffer::Helper {
public:
    ColorBufferHelper(FrameBuffer* fb) : mFb(fb) {}

    virtual bool setupContext() {
        return mFb->bind_locked();
    }

    virtual void teardownContext() {
        mFb->unbind_locked();
    }

    virtual TextureDraw* getTextureDraw() const {
        return mFb->getTextureDraw();
    }
private:
    FrameBuffer* mFb;
};

}  // namespace

FrameBuffer *FrameBuffer::s_theFrameBuffer = NULL;
HandleType FrameBuffer::s_nextHandle = 0;

static char* getGLES2ExtensionString(EGLDisplay p_dpy)
{
    EGLConfig config;
    EGLSurface surface;

    static const GLint configAttribs[] = {
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_NONE
    };

    int n;
    if (!s_egl.eglChooseConfig(p_dpy, configAttribs,
                               &config, 1, &n) || n == 0) {
        ERR("%s: Could not find GLES 2.x config!\n", __FUNCTION__);
        return NULL;
    }


    static const EGLint pbufAttribs[] = {
        EGL_WIDTH, 1,
        EGL_HEIGHT, 1,
        EGL_NONE
    };

    surface = s_egl.eglCreatePbufferSurface(p_dpy, config, pbufAttribs);
    if (surface == EGL_NO_SURFACE) {
        ERR("%s: Could not create GLES 2.x Pbuffer!\n", __FUNCTION__);
        return NULL;
    }

    static const GLint gles2ContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    EGLContext ctx = s_egl.eglCreateContext(p_dpy, config,
                                            EGL_NO_CONTEXT,
                                            gles2ContextAttribs);
    if (ctx == EGL_NO_CONTEXT) {
        ERR("%s: Could not create GLES 2.x Context!\n", __FUNCTION__);
        s_egl.eglDestroySurface(p_dpy, surface);
        return NULL;
    }

    if (!s_egl.eglMakeCurrent(p_dpy, surface, surface, ctx)) {
        ERR("%s: Could not make GLES 2.x context current!\n", __FUNCTION__);
        s_egl.eglDestroySurface(p_dpy, surface);
        s_egl.eglDestroyContext(p_dpy, ctx);
        return NULL;
    }

    // the string pointer may become invalid when the context is destroyed
    const char* s = (const char*)s_gles2.glGetString(GL_EXTENSIONS);
    char* extString = strdup(s ? s : "");

    // It is rare but some drivers actually fail this...
    if (!s_egl.eglMakeCurrent(p_dpy, NULL, NULL, NULL)) {
        ERR("%s: Could not unbind context. Please try updating graphics card driver!\n", __FUNCTION__);
        free(extString);
        return NULL;
    }
    s_egl.eglDestroyContext(p_dpy, ctx);
    s_egl.eglDestroySurface(p_dpy, surface);

    return extString;
}

void FrameBuffer::finalize(){
    m_colorbuffers.clear();
    if (m_useSubWindow) {
        removeSubWindow();
    }
    m_windows.clear();
    m_contexts.clear();
    s_egl.eglMakeCurrent(m_eglDisplay, NULL, NULL, NULL);
    s_egl.eglDestroyContext(m_eglDisplay, m_eglContext);
    s_egl.eglDestroyContext(m_eglDisplay, m_pbufContext);
    s_egl.eglDestroySurface(m_eglDisplay, m_pbufSurface);
}

bool FrameBuffer::initialize(int width, int height, bool useSubWindow)
{
    GL_LOG("FrameBuffer::initialize");
    if (s_theFrameBuffer != NULL) {
        return true;
    }

    //
    // allocate space for the FrameBuffer object
    //
    FrameBuffer *fb = new FrameBuffer(width, height, useSubWindow);
    if (!fb) {
        ERR("Failed to create fb\n");
        return false;
    }

    //
    // Initialize backend EGL display
    //
    fb->m_eglDisplay = s_egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (fb->m_eglDisplay == EGL_NO_DISPLAY) {
        ERR("Failed to Initialize backend EGL display\n");
        delete fb;
        return false;
    }

    GL_LOG("call eglInitialize");
    if (!s_egl.eglInitialize(fb->m_eglDisplay,
                             &fb->m_caps.eglMajor,
                             &fb->m_caps.eglMinor)) {
        ERR("Failed to eglInitialize\n");
        GL_LOG("Failed to eglInitialize");
        delete fb;
        return false;
    }

    DBG("egl: %d %d\n", fb->m_caps.eglMajor, fb->m_caps.eglMinor);
    GL_LOG("egl: %d %d", fb->m_caps.eglMajor, fb->m_caps.eglMinor);
    s_egl.eglBindAPI(EGL_OPENGL_ES_API);

    //
    // if GLES2 plugin has loaded - try to make GLES2 context and
    // get GLES2 extension string
    //
    char* gles2Extensions = NULL;
    gles2Extensions = getGLES2ExtensionString(fb->m_eglDisplay);
    if (!gles2Extensions) {
        // Could not create GLES2 context - drop GL2 capability
        ERR("Failed to obtain GLES 2.x extensions string!\n");
        delete fb;
        return false;
    }

    //
    // Create EGL context for framebuffer post rendering.
    //
    GLint surfaceType = (useSubWindow ? EGL_WINDOW_BIT : 0) | EGL_PBUFFER_BIT;

    // On Linux, we need RGB888 exactly, or eglMakeCurrent will fail,
    // as glXMakeContextCurrent needs to match the format of the
    // native pixmap.
    EGLint wantedRedSize = 8;
    EGLint wantedGreenSize = 8;
    EGLint wantedBlueSize = 8;
    EGLint wantedAlphaSize = 0;

    const GLint configAttribs[] = {
        EGL_RED_SIZE, wantedRedSize,
        EGL_GREEN_SIZE, wantedGreenSize,
        EGL_BLUE_SIZE, wantedBlueSize,
        EGL_ALPHA_SIZE, wantedAlphaSize,
        EGL_SURFACE_TYPE, surfaceType,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_NONE
    };

    EGLint total_num_configs = 0;
    s_egl.eglGetConfigs(fb->m_eglDisplay, NULL, 0, &total_num_configs);

    std::vector<EGLConfig> all_configs(total_num_configs);
    EGLint total_egl_compatible_configs = 0;
    s_egl.eglChooseConfig(fb->m_eglDisplay,
                          configAttribs,
                          &all_configs[0],
                          total_num_configs,
                          &total_egl_compatible_configs);

    uint32_t total_exact_matches = 0;
    std::vector<EGLint> exact_match_indices;
    for (EGLint i = 0; i < total_egl_compatible_configs; i++) {
        EGLint r,g,b,a;
        EGLConfig c = all_configs[i];
        s_egl.eglGetConfigAttrib(fb->m_eglDisplay, c, EGL_RED_SIZE, &r);
        s_egl.eglGetConfigAttrib(fb->m_eglDisplay, c, EGL_GREEN_SIZE, &g);
        s_egl.eglGetConfigAttrib(fb->m_eglDisplay, c, EGL_BLUE_SIZE, &b);
        s_egl.eglGetConfigAttrib(fb->m_eglDisplay, c, EGL_ALPHA_SIZE, &a);

        if (r == wantedRedSize &&
            g == wantedGreenSize &&
            b == wantedBlueSize &&
            a == wantedAlphaSize) {
            total_exact_matches++;
            exact_match_indices.push_back(i);
        }
    }

    if (exact_match_indices.size() == 0) {
        ERR("Failed on eglChooseConfig\n");
        free(gles2Extensions);
        delete fb;
        return false;
    }

    fb->m_eglConfig = all_configs[exact_match_indices[0]];

    static const GLint glContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    GL_LOG("attempting to create egl context");
    fb->m_eglContext = s_egl.eglCreateContext(fb->m_eglDisplay,
                                              fb->m_eglConfig,
                                              EGL_NO_CONTEXT,
                                              glContextAttribs);
    if (fb->m_eglContext == EGL_NO_CONTEXT) {
        ERR("Failed to create context 0x%x\n", s_egl.eglGetError());
        free(gles2Extensions);
        delete fb;
        return false;
    }

    GL_LOG("attempting to create egl pbuffer context");
    //
    // Create another context which shares with the eglContext to be used
    // when we bind the pbuffer. That prevent switching drawable binding
    // back and forth on framebuffer context.
    // The main purpose of it is to solve a "blanking" behaviour we see on
    // on Mac platform when switching binded drawable for a context however
    // it is more efficient on other platforms as well.
    //
    fb->m_pbufContext = s_egl.eglCreateContext(fb->m_eglDisplay,
                                               fb->m_eglConfig,
                                               fb->m_eglContext,
                                               glContextAttribs);
    if (fb->m_pbufContext == EGL_NO_CONTEXT) {
        ERR("Failed to create Pbuffer Context 0x%x\n", s_egl.eglGetError());
        free(gles2Extensions);
        delete fb;
        return false;
    }

    GL_LOG("context creation successful");
    //
    // create a 1x1 pbuffer surface which will be used for binding
    // the FB context.
    // The FB output will go to a subwindow, if one exist.
    //
    static const EGLint pbufAttribs[] = {
        EGL_WIDTH, 1,
        EGL_HEIGHT, 1,
        EGL_NONE
    };

    fb->m_pbufSurface = s_egl.eglCreatePbufferSurface(fb->m_eglDisplay,
                                                      fb->m_eglConfig,
                                                      pbufAttribs);
    if (fb->m_pbufSurface == EGL_NO_SURFACE) {
        ERR("Failed to create pbuf surface for FB 0x%x\n", s_egl.eglGetError());
        free(gles2Extensions);
        delete fb;
        return false;
    }

    GL_LOG("attempting to make context current");
    // Make the context current
    ScopedBind bind(fb);
    if (!bind.isValid()) {
        ERR("Failed to make current\n");
        free(gles2Extensions);
        delete fb;
        return false;
    }
    GL_LOG("context-current successful");

    //
    // Initilize framebuffer capabilities
    //
    //const char* gles2Extensions = (const char *)s_gles2.glGetString(GL_EXTENSIONS);
    bool has_gl_oes_image = false;

//     printf("GLES2 [%s]\n", gles2Extensions);

    has_gl_oes_image = true;

    if (has_gl_oes_image) {
        has_gl_oes_image &= strstr(gles2Extensions, "GL_OES_EGL_image") != NULL;
    }
    free((void*)gles2Extensions);
    gles2Extensions = NULL;

    const char *eglExtensions = s_egl.eglQueryString(fb->m_eglDisplay,
                                                     EGL_EXTENSIONS);

    if (eglExtensions && has_gl_oes_image) {
        fb->m_caps.has_eglimage_texture_2d =
             strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image") != NULL;
        fb->m_caps.has_eglimage_renderbuffer =
             strstr(eglExtensions, "EGL_KHR_gl_renderbuffer_image") != NULL;
    }
    else {
        fb->m_caps.has_eglimage_texture_2d = false;
        fb->m_caps.has_eglimage_renderbuffer = false;
    }

    //
    // Fail initialization if not all of the following extensions
    // exist:
    //     EGL_KHR_gl_texture_2d_image
    //     GL_OES_EGL_IMAGE (by both GLES implementations [1 and 2])
    //
    if (!fb->m_caps.has_eglimage_texture_2d) {
        ERR("Failed: Missing egl_image related extension(s)\n");
        bind.release();
        delete fb;
        return false;
    }

    GL_LOG("host system has enough extensions");
    //
    // Initialize set of configs
    //
    fb->m_configs = new FbConfigList(fb->m_eglDisplay);
    if (fb->m_configs->empty()) {
        ERR("Failed: Initialize set of configs\n");
        bind.release();
        delete fb;
        return false;
    }

    //
    // Check that we have config for each GLES and GLES2
    //
    size_t nConfigs = fb->m_configs->size();
    int nGLConfigs = 0;
    int nGL2Configs = 0;
    for (size_t i = 0; i < nConfigs; ++i) {
        GLint rtype = fb->m_configs->get(i)->getRenderableType();
        if (0 != (rtype & EGL_OPENGL_ES_BIT)) {
            nGLConfigs++;
        }
        if (0 != (rtype & EGL_OPENGL_ES2_BIT)) {
            nGL2Configs++;
        }
    }

    //
    // Don't fail initialization if no GLES configs exist
    //

    //
    // If no configs at all, exit
    //
    if (nGLConfigs + nGL2Configs == 0) {
        ERR("Failed: No GLES 2.x configs found!\n");
        bind.release();
        delete fb;
        return false;
    }

    GL_LOG("There are sufficient EGLconfigs available");

    //
    // Cache the GL strings so we don't have to think about threading or
    // current-context when asked for them.
    //
    fb->m_glVendor = (const char*)s_gles2.glGetString(GL_VENDOR);
    fb->m_glRenderer = (const char*)s_gles2.glGetString(GL_RENDERER);
    fb->m_glVersion = (const char*)s_gles2.glGetString(GL_VERSION);

    fb->m_textureDraw = new TextureDraw();
    if (!fb->m_textureDraw) {
        ERR("Failed: creation of TextureDraw instance\n");
        bind.release();
        delete fb;
        return false;
    }

    // release the FB context
    bind.release();

    //
    // Keep the singleton framebuffer pointer
    //
    s_theFrameBuffer = fb;
    GL_LOG("basic EGL initialization successful");
    return true;
}

FrameBuffer::FrameBuffer(int p_width, int p_height, bool useSubWindow) :
    m_framebufferWidth(p_width),
    m_framebufferHeight(p_height),
    m_windowWidth(p_width),
    m_windowHeight(p_height),
    m_useSubWindow(useSubWindow),
    m_fpsStats(getenv("SHOW_FPS_STATS") != nullptr),
    m_colorBufferHelper(new ColorBufferHelper(this)) {}

FrameBuffer::~FrameBuffer() {
    delete m_textureDraw;
    delete m_configs;
    delete m_colorBufferHelper;
    free(m_fbImage);
}

void FrameBuffer::setPostCallback(emugl::Renderer::OnPostCallback onPost, void* onPostContext)
{
    emugl::Mutex::AutoLock mutex(m_lock);
    m_onPost = onPost;
    m_onPostContext = onPostContext;
    if (m_onPost && !m_fbImage) {
        m_fbImage = (unsigned char*)malloc(4 * m_framebufferWidth * m_framebufferHeight);
        if (!m_fbImage) {
            ERR("out of memory, cancelling OnPost callback");
            m_onPost = NULL;
            m_onPostContext = NULL;
            return;
        }
    }
}

static void subWindowRepaint(void* param) {
    auto fb = static_cast<FrameBuffer*>(param);
    fb->repost();
}

bool FrameBuffer::setupSubWindow(FBNativeWindowType p_window,
                                 int wx,
                                 int wy,
                                 int ww,
                                 int wh,
                                 int fbw,
                                 int fbh,
                                 float dpr,
                                 float zRot) {
    bool success = false;

    if (!m_useSubWindow) {
        ERR("%s: Cannot create native sub-window in this configuration\n",
            __FUNCTION__);
        return false;
    }

    emugl::Mutex::AutoLock mutex(m_lock);

    // If the subwindow doesn't exist, create it with the appropriate dimensions
    if (!m_subWin) {

        // Create native subwindow for FB display output
        m_x = wx;
        m_y = wy;
        m_windowWidth = ww;
        m_windowHeight = wh;

        m_subWin = createSubWindow(p_window, m_x, m_y,
                                   m_windowWidth, m_windowHeight, subWindowRepaint, this);
        if (m_subWin) {
            m_nativeWindow = p_window;

            // create EGLSurface from the generated subwindow
            m_eglSurface = s_egl.eglCreateWindowSurface(m_eglDisplay,
                                                        m_eglConfig,
                                                        m_subWin,
                                                        NULL);

            if (m_eglSurface == EGL_NO_SURFACE) {
                // NOTE: This can typically happen with software-only renderers like OSMesa.
                destroySubWindow(m_subWin);
                m_subWin = (EGLNativeWindowType)0;
            } else {
                m_px = 0;
                m_py = 0;

                success = true;
            }
        }
    }

    // At this point, if the subwindow doesn't exist, it is because it either couldn't be created
    // in the first place or the EGLSurface couldn't be created.
    if (m_subWin && bindSubwin_locked()) {

        // Only attempt to update window geometry if anything has actually changed.
        bool updateSubWindow = !(m_x == wx && m_y == wy &&
                                 m_windowWidth == ww && m_windowHeight == wh);

        // On Mac, since window coordinates are Y-up and not Y-down, the
        // subwindow may not change dimensions, but because the main window
        // did, the subwindow technically needs to be re-positioned. This
        // can happen on rotation, so a change in Z-rotation can be checked
        // for this case. However, this *should not* be done on Windows/Linux,
        // because the functions used to resize a native window on those hosts
        // will block if the shape doesn't actually change, freezing the
        // emulator.
#if defined(__APPLE__)
        updateSubWindow |= (m_zRot != zRot);
#endif
        if (updateSubWindow) {

            m_x = wx;
            m_y = wy;
            m_windowWidth = ww;
            m_windowHeight = wh;

            success = ::moveSubWindow(m_nativeWindow, m_subWin,
                                      m_x, m_y, m_windowWidth, m_windowHeight);

        // Otherwise, ensure that at least viewport parameters are properly updated.
        } else {
            success = true;
        }

        if (success) {
            // Subwin creation or movement was successful,
            // update viewport and z rotation and draw
            // the last posted color buffer.
            s_gles2.glViewport(0, 0, fbw * dpr, fbh * dpr);
            m_dpr = dpr;
            m_zRot = zRot;
            if (m_lastPostedColorBuffer) {
                post(m_lastPostedColorBuffer, false);
            } else {
                s_gles2.glClear(GL_COLOR_BUFFER_BIT |
                                GL_DEPTH_BUFFER_BIT |
                                GL_STENCIL_BUFFER_BIT);
                s_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface);
            }
        }
        unbind_locked();
    }

    return success;
}

bool FrameBuffer::removeSubWindow() {
    if (!m_useSubWindow) {
        ERR("%s: Cannot remove native sub-window in this configuration\n",
            __FUNCTION__);
        return false;
    }
    bool removed = false;
    emugl::Mutex::AutoLock mutex(m_lock);
    if (m_subWin) {
        s_egl.eglMakeCurrent(m_eglDisplay, NULL, NULL, NULL);
        s_egl.eglDestroySurface(m_eglDisplay, m_eglSurface);
        destroySubWindow(m_subWin);

        m_eglSurface = EGL_NO_SURFACE;
        m_subWin = (EGLNativeWindowType)0;
        removed = true;
    }
    return removed;
}

HandleType FrameBuffer::genHandle()
{
    HandleType id;
    do {
        id = ++s_nextHandle;
    } while( id == 0 ||
             m_contexts.find(id) != m_contexts.end() ||
             m_windows.find(id) != m_windows.end() );

    return id;
}

HandleType FrameBuffer::createColorBuffer(int p_width, int p_height,
                                          GLenum p_internalFormat)
{
    emugl::Mutex::AutoLock mutex(m_lock);
    HandleType ret = 0;

    ColorBufferPtr cb(ColorBuffer::create(
            getDisplay(),
            p_width,
            p_height,
            p_internalFormat,
            getCaps().has_eglimage_texture_2d,
            m_colorBufferHelper));
    if (cb.get() != NULL) {
        ret = genHandle();
        m_colorbuffers[ret].cb = cb;
        m_colorbuffers[ret].refcount = 1;

        RenderThreadInfo *tInfo = RenderThreadInfo::get();
        uint64_t puid = tInfo->m_puid;
        if (puid) {
            m_procOwnedColorBuffers[puid].insert(ret);
        }
    }
    return ret;
}

HandleType FrameBuffer::createRenderContext(int p_config, HandleType p_share,
                                            bool p_isGL2)
{
    emugl::Mutex::AutoLock mutex(m_lock);
    emugl::ReadWriteMutex::AutoWriteLock contextLock(m_contextStructureLock);
    HandleType ret = 0;

    const FbConfig* config = getConfigs()->get(p_config);
    if (!config) {
        return ret;
    }

    RenderContextPtr share;
    if (p_share != 0) {
        RenderContextMap::iterator s(m_contexts.find(p_share));
        if (s == m_contexts.end()) {
            return ret;
        }
        share = (*s).second;
    }
    EGLContext sharedContext =
            share.get() ? share->getEGLContext() : EGL_NO_CONTEXT;

    RenderContextPtr rctx(RenderContext::create(
        m_eglDisplay, config->getEglConfig(), sharedContext, p_isGL2));
    if (rctx.get() != NULL) {
        ret = genHandle();
        m_contexts[ret] = rctx;
        RenderThreadInfo *tinfo = RenderThreadInfo::get();
        uint64_t puid = tinfo->m_puid;
        // The new emulator manages render contexts per guest process.
        // Fall back to per-thread management if the system image does not
        // support it.
        if (puid) {
            m_procOwnedRenderContext[puid].insert(ret);
        } else {
            tinfo->m_contextSet.insert(ret);
        }
    }

    return ret;
}

HandleType FrameBuffer::createWindowSurface(int p_config, int p_width, int p_height)
{
    emugl::Mutex::AutoLock mutex(m_lock);

    HandleType ret = 0;

    const FbConfig* config = getConfigs()->get(p_config);
    if (!config) {
        return ret;
    }

    WindowSurfacePtr win(WindowSurface::create(
            getDisplay(), config->getEglConfig(), p_width, p_height));
    if (win.get() != NULL) {
        ret = genHandle();
        m_windows[ret] = std::pair<WindowSurfacePtr, HandleType>(win,0);
        RenderThreadInfo *tinfo = RenderThreadInfo::get();
        tinfo->m_windowSet.insert(ret);
    }

    return ret;
}

void FrameBuffer::drainRenderContext()
{
    emugl::Mutex::AutoLock mutex(m_lock);
    emugl::ReadWriteMutex::AutoWriteLock contextLock(m_contextStructureLock);
    RenderThreadInfo *tinfo = RenderThreadInfo::get();
    if (tinfo->m_contextSet.empty()) return;
    for (std::set<HandleType>::iterator it = tinfo->m_contextSet.begin();
            it != tinfo->m_contextSet.end(); ++it) {
        HandleType contextHandle = *it;
        m_contexts.erase(contextHandle);
    }
    tinfo->m_contextSet.clear();
}

void FrameBuffer::drainWindowSurface()
{
    emugl::Mutex::AutoLock mutex(m_lock);
    RenderThreadInfo *tinfo = RenderThreadInfo::get();
    if (tinfo->m_windowSet.empty()) return;
    for (std::set<HandleType>::iterator it = tinfo->m_windowSet.begin();
            it != tinfo->m_windowSet.end(); ++it) {
        HandleType windowHandle = *it;
        if (m_windows.find(windowHandle) != m_windows.end()) {
            HandleType oldColorBufferHandle = m_windows[windowHandle].second;
            if (oldColorBufferHandle) {
                ColorBufferMap::iterator cit(m_colorbuffers.find(oldColorBufferHandle));
                if (cit != m_colorbuffers.end()) {
                    if (--(*cit).second.refcount == 0) { m_colorbuffers.erase(cit); }
                }
            }
            m_windows.erase(windowHandle);
        }
    }
    tinfo->m_windowSet.clear();
}

void FrameBuffer::DestroyRenderContext(HandleType p_context)
{
    emugl::Mutex::AutoLock mutex(m_lock);
    emugl::ReadWriteMutex::AutoWriteLock contextLock(m_contextStructureLock);
    m_contexts.erase(p_context);
    RenderThreadInfo *tinfo = RenderThreadInfo::get();
    uint64_t puid = tinfo->m_puid;
    // The new emulator manages render contexts per guest process.
    // Fall back to per-thread management if the system image does not
    // support it.
    if (puid) {
        auto ite = m_procOwnedRenderContext.find(puid);
        if (ite != m_procOwnedRenderContext.end()) {
            ite->second.erase(p_context);
        }
    } else {
        tinfo->m_contextSet.erase(p_context);
    }
}

void FrameBuffer::DestroyWindowSurface(HandleType p_surface)
{
    emugl::Mutex::AutoLock mutex(m_lock);
    if (m_windows.erase(p_surface) != 0) {
        RenderThreadInfo *tinfo = RenderThreadInfo::get();
        tinfo->m_windowSet.erase(p_surface);
    }
}

int FrameBuffer::openColorBuffer(HandleType p_colorbuffer) {
    RenderThreadInfo *tInfo = RenderThreadInfo::get();

    emugl::Mutex::AutoLock mutex(m_lock);

    ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer));
    if (c == m_colorbuffers.end()) {
        // bad colorbuffer handle
        ERR("FB: openColorBuffer cb handle %#x not found\n", p_colorbuffer);
        return -1;
    }
    (*c).second.refcount++;

    uint64_t puid = tInfo->m_puid;
    if (puid) {
        m_procOwnedColorBuffers[puid].insert(p_colorbuffer);
    }
    return 0;
}

void FrameBuffer::closeColorBuffer(HandleType p_colorbuffer) {
    RenderThreadInfo *tInfo = RenderThreadInfo::get();

    emugl::Mutex::AutoLock mutex(m_lock);
    closeColorBufferLocked(p_colorbuffer);
    uint64_t puid = tInfo->m_puid;
    if (puid) {
        auto ite = m_procOwnedColorBuffers.find(puid);
        if (ite != m_procOwnedColorBuffers.end()) {
            ite->second.erase(p_colorbuffer);
        }
    }
}

void FrameBuffer::closeColorBufferLocked(HandleType p_colorbuffer) {
    ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer));
    if (c == m_colorbuffers.end()) {
        // This is harmless: it is normal for guest system to issue
        // closeColorBuffer command when the color buffer is already
        // garbage collected on the host. (we dont have a mechanism
        // to give guest a notice yet)
        return;
    }
    if (--(*c).second.refcount == 0) {
        m_colorbuffers.erase(c);
    }
}

void FrameBuffer::cleanupProcGLObjects(uint64_t puid) {
    emugl::Mutex::AutoLock mutex(m_lock);
    // Clean up color buffers.
    // A color buffer needs to be closed as many times as it is opened by
    // the guest process, to give the correct reference count.
    // (Note that a color buffer can be shared across guest processes.)
    {
        auto procIte = m_procOwnedColorBuffers.find(puid);
        if (procIte != m_procOwnedColorBuffers.end()) {
            for (auto cb: procIte->second) {
                closeColorBufferLocked(cb);
            }
            m_procOwnedColorBuffers.erase(procIte);
        }
    }

    // Clean up EGLImage handles
    {
        // Bind context before potentially triggering any gl calls
        ScopedBind bind(this);
        auto procIte = m_procOwnedEGLImages.find(puid);
        if (procIte != m_procOwnedEGLImages.end()) {
            for (auto eglImg : procIte->second) {
                s_egl.eglDestroyImageKHR(m_eglDisplay,
                            reinterpret_cast<EGLImageKHR>((HandleType)eglImg));
            }
            m_procOwnedEGLImages.erase(procIte);
        }
    }

    // Cleanup render contexts
    {
        auto procIte = m_procOwnedRenderContext.find(puid);
        if (procIte != m_procOwnedRenderContext.end()) {
            for (auto ctx: procIte->second) {
                m_contexts.erase(ctx);
            }
            m_procOwnedRenderContext.erase(procIte);
        }
    }
}

bool FrameBuffer::flushWindowSurfaceColorBuffer(HandleType p_surface)
{
    emugl::Mutex::AutoLock mutex(m_lock);

    WindowSurfaceMap::iterator w( m_windows.find(p_surface) );
    if (w == m_windows.end()) {
        ERR("FB::flushWindowSurfaceColorBuffer: window handle %#x not found\n", p_surface);
        // bad surface handle
        return false;
    }

    WindowSurface* surface = (*w).second.first.get();
    surface->flushColorBuffer();

    return true;
}

bool FrameBuffer::setWindowSurfaceColorBuffer(HandleType p_surface,
                                              HandleType p_colorbuffer)
{
    emugl::Mutex::AutoLock mutex(m_lock);

    WindowSurfaceMap::iterator w( m_windows.find(p_surface) );
    if (w == m_windows.end()) {
        // bad surface handle
        ERR("%s: bad window surface handle %#x\n", __FUNCTION__, p_surface);
        return false;
    }

    ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
    if (c == m_colorbuffers.end()) {
        DBG("%s: bad color buffer handle %#x\n", __FUNCTION__, p_colorbuffer);
        // bad colorbuffer handle
        return false;
    }

    (*w).second.first->setColorBuffer((*c).second.cb);
    (*w).second.second = p_colorbuffer;
    return true;
}

void FrameBuffer::readColorBuffer(HandleType p_colorbuffer,
                                    int x, int y, int width, int height,
                                    GLenum format, GLenum type, void *pixels)
{
    emugl::Mutex::AutoLock mutex(m_lock);

    ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
    if (c == m_colorbuffers.end()) {
        // bad colorbuffer handle
        return;
    }

    (*c).second.cb->readPixels(x, y, width, height, format, type, pixels);
}

bool FrameBuffer::updateColorBuffer(HandleType p_colorbuffer,
                                    int x, int y, int width, int height,
                                    GLenum format, GLenum type, void *pixels)
{
    emugl::Mutex::AutoLock mutex(m_lock);

    ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
    if (c == m_colorbuffers.end()) {
        // bad colorbuffer handle
        return false;
    }

    (*c).second.cb->subUpdate(x, y, width, height, format, type, pixels);

    return true;
}

bool FrameBuffer::bindColorBufferToTexture(HandleType p_colorbuffer)
{
    emugl::Mutex::AutoLock mutex(m_lock);

    ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
    if (c == m_colorbuffers.end()) {
        // bad colorbuffer handle
        return false;
    }

    return (*c).second.cb->bindToTexture();
}

bool FrameBuffer::bindColorBufferToRenderbuffer(HandleType p_colorbuffer)
{
    emugl::Mutex::AutoLock mutex(m_lock);

    ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
    if (c == m_colorbuffers.end()) {
        // bad colorbuffer handle
        return false;
    }

    return (*c).second.cb->bindToRenderbuffer();
}

bool FrameBuffer::bindContext(HandleType p_context,
                              HandleType p_drawSurface,
                              HandleType p_readSurface)
{
    emugl::Mutex::AutoLock mutex(m_lock);

    WindowSurfacePtr draw, read;
    RenderContextPtr ctx;

    //
    // if this is not an unbind operation - make sure all handles are good
    //
    if (p_context || p_drawSurface || p_readSurface) {
        RenderContextMap::iterator r( m_contexts.find(p_context) );
        if (r == m_contexts.end()) {
            // bad context handle
            return false;
        }

        ctx = (*r).second;
        WindowSurfaceMap::iterator w( m_windows.find(p_drawSurface) );
        if (w == m_windows.end()) {
            // bad surface handle
            return false;
        }
        draw = (*w).second.first;

        if (p_readSurface != p_drawSurface) {
            WindowSurfaceMap::iterator w( m_windows.find(p_readSurface) );
            if (w == m_windows.end()) {
                // bad surface handle
                return false;
            }
            read = (*w).second.first;
        }
        else {
            read = draw;
        }
    }

    if (!s_egl.eglMakeCurrent(m_eglDisplay,
                              draw ? draw->getEGLSurface() : EGL_NO_SURFACE,
                              read ? read->getEGLSurface() : EGL_NO_SURFACE,
                              ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT)) {
        ERR("eglMakeCurrent failed\n");
        return false;
    }

    if (ctx) {
        if (ctx.get()->getEmulatedGLES1Context()) {
            DBG("%s: found emulated gles1 context @ %p\n", __FUNCTION__, ctx.get()->getEmulatedGLES1Context());
            s_gles1.set_current_gles_context(ctx.get()->getEmulatedGLES1Context());
            DBG("%s: set emulated gles1 context current in thread info\n", __FUNCTION__);

            if (draw.get() == NULL) {
                DBG("%s: setup make current (null draw surface)\n", __FUNCTION__);
                s_gles1.make_current_setup(0, 0);
            } else {
                DBG("%s: setup make current (draw surface %ux%u)\n", __FUNCTION__, draw->getWidth(), draw->getHeight());
                s_gles1.make_current_setup(draw->getWidth(), draw->getHeight());
            }
            DBG("%s: set up the emulated gles1 context's info\n", __FUNCTION__);
        }
    }

    //
    // Bind the surface(s) to the context
    //
    RenderThreadInfo *tinfo = RenderThreadInfo::get();
    WindowSurfacePtr bindDraw, bindRead;
    if (draw.get() == NULL && read.get() == NULL) {
        // Unbind the current read and draw surfaces from the context
        bindDraw = tinfo->currDrawSurf;
        bindRead = tinfo->currReadSurf;
    } else {
        bindDraw = draw;
        bindRead = read;
    }

    if (bindDraw.get() != NULL && bindRead.get() != NULL) {
        if (bindDraw.get() != bindRead.get()) {
            bindDraw->bind(ctx, WindowSurface::BIND_DRAW);
            bindRead->bind(ctx, WindowSurface::BIND_READ);
        }
        else {
            bindDraw->bind(ctx, WindowSurface::BIND_READDRAW);
        }
    }

    //
    // update thread info with current bound context
    //
    tinfo->currContext = ctx;
    tinfo->currDrawSurf = draw;
    tinfo->currReadSurf = read;
    if (ctx) {
        if (ctx->isGL2()) tinfo->m_gl2Dec.setContextData(&ctx->decoderContextData());
        else tinfo->m_glDec.setContextData(&ctx->decoderContextData());
    }
    else {
        tinfo->m_glDec.setContextData(NULL);
        tinfo->m_gl2Dec.setContextData(NULL);
    }
    return true;
}

HandleType FrameBuffer::createClientImage(HandleType context, EGLenum target, GLuint buffer)
{
    RenderContextPtr ctx;

    if (context) {
        RenderContextMap::iterator r( m_contexts.find(context) );
        if (r == m_contexts.end()) {
            // bad context handle
            return false;
        }

        ctx = (*r).second;
    }

    EGLContext eglContext = ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT;
    EGLImageKHR image = s_egl.eglCreateImageKHR(
                            m_eglDisplay, eglContext, target,
                            reinterpret_cast<EGLClientBuffer>(buffer), NULL);
    HandleType imgHnd = (HandleType)reinterpret_cast<uintptr_t>(image);

    RenderThreadInfo *tInfo = RenderThreadInfo::get();
    uint64_t puid = tInfo->m_puid;
    if (puid) {
        emugl::Mutex::AutoLock mutex(m_lock);
        m_procOwnedEGLImages[puid].insert(imgHnd);
    }
    return imgHnd;
}

EGLBoolean FrameBuffer::destroyClientImage(HandleType image) {
    // eglDestroyImageKHR has its own lock  already.
    EGLBoolean ret = s_egl.eglDestroyImageKHR(m_eglDisplay,
                                reinterpret_cast<EGLImageKHR>(image));
    if (!ret) return false;
    RenderThreadInfo *tInfo = RenderThreadInfo::get();
    uint64_t puid = tInfo->m_puid;
    if (puid) {
        emugl::Mutex::AutoLock mutex(m_lock);
        m_procOwnedEGLImages[puid].erase(image);
        // We don't explicitly call m_procOwnedEGLImages.erase(puid) when the size
        // reaches 0, since it could go between zero and one many times in the
        // lifetime of a process.
        // It will be cleaned up by cleanupProcGLObjects(puid) when the process is
        // dead.
    }
    return true;
}

//
// The framebuffer lock should be held when calling this function !
//
bool FrameBuffer::bind_locked()
{
    EGLContext prevContext = s_egl.eglGetCurrentContext();
    EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
    EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);

    if (prevContext != m_pbufContext || prevReadSurf != m_pbufSurface
        || prevDrawSurf != m_pbufSurface) {
        if (!s_egl.eglMakeCurrent(m_eglDisplay, m_pbufSurface,
                                  m_pbufSurface, m_pbufContext)) {
            ERR("eglMakeCurrent failed\n");
            return false;
        }
    } else {
        ERR("Nested %s call detected, should never happen", __func__);
    }

    m_prevContext = prevContext;
    m_prevReadSurf = prevReadSurf;
    m_prevDrawSurf = prevDrawSurf;
    return true;
}

bool FrameBuffer::bindSubwin_locked()
{
    EGLContext prevContext = s_egl.eglGetCurrentContext();
    EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
    EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);

    if (prevContext != m_eglContext || prevReadSurf != m_eglSurface
        || prevDrawSurf != m_eglSurface) {
        if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface,
                                  m_eglSurface, m_eglContext)) {
            ERR("eglMakeCurrent failed\n");
            return false;
        }
    } else {
        ERR("Nested %s call detected, should never happen", __func__);
    }

    //
    // initialize GL state in eglContext if not yet initilaized
    //
    if (!m_eglContextInitialized) {
        m_eglContextInitialized = true;
    }

    m_prevContext = prevContext;
    m_prevReadSurf = prevReadSurf;
    m_prevDrawSurf = prevDrawSurf;
    return true;
}

bool FrameBuffer::unbind_locked()
{
    EGLContext curContext = s_egl.eglGetCurrentContext();
    EGLSurface curReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
    EGLSurface curDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);

    if (m_prevContext != curContext || m_prevReadSurf != curReadSurf ||
        m_prevDrawSurf != curDrawSurf) {
        if (!s_egl.eglMakeCurrent(m_eglDisplay, m_prevDrawSurf,
                                  m_prevReadSurf, m_prevContext)) {
            return false;
        }
    }

    m_prevContext = EGL_NO_CONTEXT;
    m_prevReadSurf = EGL_NO_SURFACE;
    m_prevDrawSurf = EGL_NO_SURFACE;
    return true;
}

void FrameBuffer::createTrivialContext(HandleType shared,
                                       HandleType* contextOut,
                                       HandleType* surfOut) {
    assert(contextOut);
    assert(surfOut);

    *contextOut = createRenderContext(0, shared, true);
    // Zero size is formally allowed here, but SwiftShader doesn't like it and
    // fails.
    *surfOut = createWindowSurface(0, 1, 1);
}

bool FrameBuffer::post(HandleType p_colorbuffer, bool needLockAndBind)
{
    if (needLockAndBind) {
        m_lock.lock();
    }
    bool ret = false;

    ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
    if (c == m_colorbuffers.end()) {
        goto EXIT;
    }

    m_lastPostedColorBuffer = p_colorbuffer;

    if (m_subWin) {
        // bind the subwindow eglSurface
        if (needLockAndBind && !bindSubwin_locked()) {
            ERR("FrameBuffer::post(): eglMakeCurrent failed\n");
            goto EXIT;
        }

        // get the viewport
        GLint vp[4];
        s_gles2.glGetIntegerv(GL_VIEWPORT, vp);

        // divide by device pixel ratio because windowing coordinates ignore DPR,
        // but the framebuffer includes DPR
        vp[2] = vp[2] / m_dpr;
        vp[3] = vp[3] / m_dpr;

        // find the x and y values at the origin when "fully scrolled"
        // multiply by 2 because the texture goes from -1 to 1, not 0 to 1
        float fx = 2.f * (vp[2] - m_windowWidth) / (float) vp[2];
        float fy = 2.f * (vp[3] - m_windowHeight) / (float) vp[3];

        // finally, compute translation values
        float dx = m_px * fx;
        float dy = m_py * fy;

        //
        // render the color buffer to the window
        //
        if (m_zRot != 0.0f) {
            s_gles2.glClear(GL_COLOR_BUFFER_BIT);
        }
        ret = (*c).second.cb->post(m_zRot, dx, dy);
        if (ret) {
            s_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface);
        }

        // restore previous binding
        if (needLockAndBind) {
            unbind_locked();
        }
    } else {
        // If there is no sub-window, don't display anything, the client will
        // rely on m_onPost to get the pixels instead.
        ret = true;
    }

    //
    // output FPS statistics
    //
    if (m_fpsStats) {
        long long currTime = android::base::System::get()->getHighResTimeUs() / 1000;
        m_statsNumFrames++;
        if (currTime - m_statsStartTime >= 1000) {
            float dt = (float)(currTime - m_statsStartTime) / 1000.0f;
            printf("FPS: %5.3f\n", (float)m_statsNumFrames / dt);
            m_statsStartTime = currTime;
            m_statsNumFrames = 0;
        }
    }

    //
    // Send framebuffer (without FPS overlay) to callback
    //
    if (m_onPost) {
        (*c).second.cb->readback(m_fbImage);
        m_onPost(m_onPostContext,
                 m_framebufferWidth,
                 m_framebufferHeight,
                 -1,
                 GL_RGBA,
                 GL_UNSIGNED_BYTE,
                 m_fbImage);
    }

EXIT:
    if (needLockAndBind) {
        m_lock.unlock();
    }
    return ret;
}

bool FrameBuffer::repost() {
    if (m_lastPostedColorBuffer) {
        return post(m_lastPostedColorBuffer);
    }
    return false;
}
