/*
 * 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.
 */
#ifndef _LIBRENDER_FRAMEBUFFER_H
#define _LIBRENDER_FRAMEBUFFER_H

#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <stdint.h>

#include <array>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <unordered_map>
#include <unordered_set>

#include "Buffer.h"
#include "Compositor.h"
#include "Display.h"
#include "DisplaySurface.h"
#include "Hwc2.h"
#include "PostCommands.h"
#include "PostWorker.h"
#include "ReadbackWorker.h"
#include "VsyncThread.h"
#include "aemu/base/AsyncResult.h"
#include "aemu/base/EventNotificationSupport.h"
#include "aemu/base/HealthMonitor.h"
#include "aemu/base/ManagedDescriptor.hpp"
#include "aemu/base/Metrics.h"
#include "aemu/base/files/Stream.h"
#include "aemu/base/synchronization/Lock.h"
#include "aemu/base/synchronization/MessageChannel.h"
#include "aemu/base/threads/Thread.h"
#include "aemu/base/threads/WorkerThread.h"
#include "gl/BufferGl.h"
#include "gl/ColorBufferGl.h"
#include "gl/CompositorGl.h"
#include "gl/DisplaySurfaceGl.h"
#include "gl/EmulatedEglConfig.h"
#include "gl/EmulatedEglContext.h"
#include "gl/EmulatedEglImage.h"
#include "gl/EmulatedEglWindowSurface.h"
#include "gl/EmulationGl.h"
#include "gl/GLESVersionDetector.h"
#include "gl/TextureDraw.h"
#include "render-utils/Renderer.h"
#include "render-utils/virtio_gpu_ops.h"
#include "render-utils/render_api.h"
#include "snapshot/common.h"
#include "utils/RenderDoc.h"
#include "vulkan/vk_util.h"

namespace gfxstream {
namespace vk {
class DisplayVk;
}  // namespace vk
}  // namespace gfxstream

namespace gfxstream {

using android::base::CreateMetricsLogger;
using emugl::HealthMonitor;
using emugl::MetricsLogger;

struct BufferRef {
    BufferPtr buffer;
};

class ProcessResources {
   public:
    // We only allow ProcessResources to be created on the heap, because the pointer to
    // mSequenceNumber shouldn't change until ProcessResources is destroyed.
    static std::unique_ptr<ProcessResources> create() {
        return std::unique_ptr<ProcessResources>(new ProcessResources());
    }
    DISALLOW_COPY_ASSIGN_AND_MOVE(ProcessResources);

    ~ProcessResources() = default;
    std::atomic<uint32_t>* getSequenceNumberPtr() const {
        return &mSequenceNumber;
    }

   private:
    ProcessResources() : mSequenceNumber(0) {}
    mutable std::atomic<uint32_t> mSequenceNumber;
};

typedef std::unordered_map<uint64_t, gl::EmulatedEglWindowSurfaceSet>
    ProcOwnedEmulatedEglWindowSurfaces;

typedef std::unordered_map<uint64_t, gl::EmulatedEglContextSet> ProcOwnedEmulatedEglContexts;

typedef std::unordered_map<uint64_t, ColorBufferSet> ProcOwnedColorBuffers;

typedef std::unordered_map<HandleType, BufferRef> BufferMap;
typedef std::unordered_multiset<HandleType> BufferSet;
typedef std::unordered_map<uint64_t, BufferSet> ProcOwnedBuffers;

typedef std::unordered_map<uint64_t, gl::EmulatedEglImageSet> ProcOwnedEmulatedEGLImages;

typedef std::unordered_map<void*, std::function<void()>> CallbackMap;
typedef std::unordered_map<uint64_t, CallbackMap> ProcOwnedCleanupCallbacks;

// The FrameBuffer class holds the global state of the emulation library on
// top of the underlying EGL/GLES implementation. It should probably be
// named "Display" instead of "FrameBuffer".
//
// There is only one global instance, that can be retrieved with getFB(),
// and which must be previously setup by calling initialize().
//
class FrameBuffer : public android::base::EventNotificationSupport<FrameBufferChangeEvent> {
   public:
    // Initialize the global instance.
    // |width| and |height| are the dimensions of the emulator GPU display
    // in pixels. |useSubWindow| is true to indicate that the caller
    // will use setupSubWindow() to let EmuGL display the GPU content in its
    // own sub-windows. If false, this means the caller will use
    // setPostCallback() instead to retrieve the content.
    // Returns true on success, false otherwise.
    static bool initialize(int width, int height, bool useSubWindow,
                           bool egl2egl);

    // Finalize the instance.
    static void finalize();

    // Setup a sub-window to display the content of the emulated GPU
    // on-top of an existing UI window. |p_window| is the platform-specific
    // parent window handle. |wx|, |wy|, |ww| and |wh| are the
    // dimensions in pixels of the sub-window, relative to the parent window's
    // coordinate. |fbw| and |fbh| are the dimensions used to initialize
    // the framebuffer, which may be different from the dimensions of the
    // sub-window (in which case scaling will be applied automatically).
    // |dpr| is the device pixel ratio of the monitor, which is needed for
    // proper panning on high-density displays (like retina)
    // |zRot| is a rotation angle in degrees, (clockwise in the Y-upwards GL
    // coordinate space).
    //
    // If a sub-window already exists, this function updates the subwindow
    // and framebuffer properties to match the given values.
    //
    // Return true on success, false otherwise.
    //
    // NOTE: This can return false for software-only EGL engines like OSMesa.
    bool setupSubWindow(FBNativeWindowType p_window, int wx, int wy, int ww,
                        int wh, int fbw, int fbh, float dpr, float zRot,
                        bool deleteExisting, bool hideWindow);

    // Remove the sub-window created by setupSubWindow(), if any.
    // Return true on success, false otherwise.
    bool removeSubWindow();

    // Return a pointer to the global instance. initialize() must be called
    // previously, or this will return NULL.
    static FrameBuffer* getFB() { return s_theFrameBuffer; }

    // Wait for a FrameBuffer instance to be initialized and ready to use.
    // This function blocks the caller until there is a valid initialized
    // object in getFB() and
    static void waitUntilInitialized();

    // Return the emulated GPU display width in pixels.
    int getWidth() const { return m_framebufferWidth; }

    // Return the emulated GPU display height in pixels.
    int getHeight() const { return m_framebufferHeight; }

    // Return the list of configs available from this display.
    const gl::EmulatedEglConfigList* getConfigs() const;

    // Set a callback that will be called each time the emulated GPU content
    // is updated. This can be relatively slow with host-based GPU emulation,
    // so only do this when you need to.
    void setPostCallback(Renderer::OnPostCallback onPost, void* onPostContext, uint32_t displayId,
                         bool useBgraReadback = false);

    // Retrieve the GL strings of the underlying EGL/GLES implementation.
    // On return, |*vendor|, |*renderer| and |*version| will point to strings
    // that are owned by the instance (and must not be freed by the caller).
    void getGLStrings(const char** vendor, const char** renderer,
                      const char** version) const {
        *vendor = m_graphicsAdapterVendor.c_str();
        *renderer = m_graphicsAdapterName.c_str();
        *version = m_graphicsApiVersion.c_str();
    }

    // Create a new EmulatedEglContext instance for this display instance.
    // |p_config| is the index of one of the configs returned by getConfigs().
    // |p_share| is either EGL_NO_CONTEXT or the handle of a shared context.
    // |version| specifies the GLES version as a GLESApi enum.
    // Return a new handle value, which will be 0 in case of error.
    HandleType createEmulatedEglContext(int p_config, HandleType p_share,
                                        gl::GLESApi version = gl::GLESApi_CM);

    // Destroy a given EmulatedEglContext instance. |p_context| is its handle
    // value as returned by createEmulatedEglContext().
    void destroyEmulatedEglContext(HandleType p_context);

    // Create a new EmulatedEglWindowSurface instance from this display instance.
    // |p_config| is the index of one of the configs returned by getConfigs().
    // |p_width| and |p_height| are the window dimensions in pixels.
    // Return a new handle value, or 0 in case of error.
    HandleType createEmulatedEglWindowSurface(int p_config, int p_width, int p_height);

    // Destroy a given EmulatedEglWindowSurface instance. |p_surcace| is its
    // handle value as returned by createEmulatedEglWindowSurface().
    void destroyEmulatedEglWindowSurface(HandleType p_surface);

    // Returns the set of ColorBuffers destroyed (for further cleanup)
    std::vector<HandleType> destroyEmulatedEglWindowSurfaceLocked(HandleType p_surface);

    void createEmulatedEglFenceSync(EGLenum type,
                                    int destroyWhenSignaled,
                                    uint64_t* outSync = nullptr,
                                    uint64_t* outSyncThread = nullptr);

    // Create a new ColorBuffer instance from this display instance.
    // |p_width| and |p_height| are its dimensions in pixels.
    // |p_internalFormat| is the OpenGL format of this color buffer.
    // |p_frameworkFormat| describes the Android frameework format of this
    // color buffer, if differing from |p_internalFormat|.
    // See ColorBuffer::create() for
    // list of valid values. Note that ColorBuffer instances are reference-
    // counted. Use openColorBuffer / closeColorBuffer to operate on the
    // internal count.
    HandleType createColorBuffer(int p_width, int p_height,
                                 GLenum p_internalFormat,
                                 FrameworkFormat p_frameworkFormat);
    // Variant of createColorBuffer except with a particular
    // handle already assigned. This is for use with
    // virtio-gpu's RESOURCE_CREATE ioctl.
    void createColorBufferWithHandle(int p_width, int p_height, GLenum p_internalFormat,
                                     FrameworkFormat p_frameworkFormat, HandleType handle);

    // Create a new data Buffer instance from this display instance.
    // The buffer will be backed by a VkBuffer and VkDeviceMemory (if Vulkan
    // is available).
    // |size| is the requested size of Buffer in bytes.
    // |memoryProperty| is the requested memory property bits of the device
    // memory.
    HandleType createBuffer(uint64_t size, uint32_t memoryProperty);

    // Variant of createBuffer except with a particular handle already
    // assigned and using device local memory. This is for use with
    // virtio-gpu's RESOURCE_CREATE ioctl for BLOB resources.
    void createBufferWithHandle(uint64_t size, HandleType handle);

    // Call this function when a render thread terminates to destroy all
    // resources it created. Necessary to avoid leaking host resources
    // when a guest application crashes, for example.
    void drainGlRenderThreadResources();

    // Call this function when a render thread terminates to destroy all
    // the remaining contexts it created. Necessary to avoid leaking host
    // contexts when a guest application crashes, for example.
    void drainGlRenderThreadContexts();

    // Call this function when a render thread terminates to destroy all
    // remaining window surface it created. Necessary to avoid leaking
    // host buffers when a guest application crashes, for example.
    void drainGlRenderThreadSurfaces();

    // Increment the reference count associated with a given ColorBuffer
    // instance. |p_colorbuffer| is its handle value as returned by
    // createColorBuffer().
    int openColorBuffer(HandleType p_colorbuffer);

    // Decrement the reference count associated with a given ColorBuffer
    // instance. |p_colorbuffer| is its handle value as returned by
    // createColorBuffer(). Note that if the reference count reaches 0,
    // the instance is destroyed automatically.
    void closeColorBuffer(HandleType p_colorbuffer);

    // Destroy a Buffer created previously. |p_buffer| is its handle value as
    // returned by createBuffer().
    void closeBuffer(HandleType p_colorbuffer);

    // The caller mustn't refer to this puid before this function returns, i.e. the creation of the
    // host process pipe must be blocked until this function returns.
    void createGraphicsProcessResources(uint64_t puid);
    // The process resource is returned so that we can destroy it on a separate thread.
    std::unique_ptr<ProcessResources> removeGraphicsProcessResources(uint64_t puid);
    // TODO(kaiyili): retire cleanupProcGLObjects in favor of removeGraphicsProcessResources.
    void cleanupProcGLObjects(uint64_t puid);

    // Equivalent for eglMakeCurrent() for the current display.
    // |p_context|, |p_drawSurface| and |p_readSurface| are the handle values
    // of the context, the draw surface and the read surface, respectively.
    // Returns true on success, false on failure.
    // Note: if all handle values are 0, this is an unbind operation.
    bool bindContext(HandleType p_context, HandleType p_drawSurface,
                     HandleType p_readSurface);

    // Return a render context pointer from its handle
    gl::EmulatedEglContextPtr getContext_locked(HandleType p_context);

    // Return a color buffer pointer from its handle
    gl::EmulatedEglWindowSurfacePtr getWindowSurface_locked(HandleType p_windowsurface);

    // Attach a ColorBuffer to a EmulatedEglWindowSurface instance.
    // See the documentation for EmulatedEglWindowSurface::setColorBuffer().
    // |p_surface| is the target EmulatedEglWindowSurface's handle value.
    // |p_colorbuffer| is the ColorBuffer handle value.
    // Returns true on success, false otherwise.
    bool setEmulatedEglWindowSurfaceColorBuffer(HandleType p_surface,
                                                HandleType p_colorbuffer);

    // Copy the content of a EmulatedEglWindowSurface's Pbuffer to its attached
    // ColorBuffer. See the documentation for
    // EmulatedEglWindowSurface::flushColorBuffer().
    // |p_surface| is the target WindowSurface's handle value.
    // Returns true on success, false on failure.
    bool flushEmulatedEglWindowSurfaceColorBuffer(HandleType p_surface);

    // Retrieves the color buffer handle associated with |p_surface|.
    // Returns 0 if there is no such handle.
    HandleType getEmulatedEglWindowSurfaceColorBufferHandle(HandleType p_surface);

    // Bind the current context's EGL_TEXTURE_2D texture to a ColorBuffer
    // instance's EGLImage. This is intended to implement
    // glEGLImageTargetTexture2DOES() for all GLES versions.
    // |p_colorbuffer| is the ColorBuffer's handle value.
    // Returns true on success, false on failure.
    bool bindColorBufferToTexture(HandleType p_colorbuffer);
    bool bindColorBufferToTexture2(HandleType p_colorbuffer);

    // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this
    // ColorBuffer's EGLImage. This is intended to implement
    // glEGLImageTargetRenderbufferStorageOES() for all GLES versions.
    // |p_colorbuffer| is the ColorBuffer's handle value.
    // Returns true on success, false on failure.
    bool bindColorBufferToRenderbuffer(HandleType p_colorbuffer);

    // Read the content of a given Buffer into client memory.
    // |p_buffer| is the Buffer's handle value.
    // |offset| and |size| are the position and size of a slice of the buffer
    // that will be read.
    // |bytes| is the address of a caller-provided buffer that will be filled
    // with the buffer data.
    void readBuffer(HandleType p_buffer, uint64_t offset, uint64_t size, void* bytes);

    // Read the content of a given ColorBuffer into client memory.
    // |p_colorbuffer| is the ColorBuffer's handle value. Similar
    // to glReadPixels(), this can be a slow operation.
    // |x|, |y|, |width| and |height| are the position and dimensions of
    // a rectangle whose pixel values will be transfered to the host.
    // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA.
    // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
    // |pixels| is the address of a caller-provided buffer that will be filled
    // with the pixel data.
    void readColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
                         int height, GLenum format, GLenum type, void* pixels);

    // Read the content of a given YUV420_888 ColorBuffer into client memory.
    // |p_colorbuffer| is the ColorBuffer's handle value. Similar
    // to glReadPixels(), this can be a slow operation.
    // |x|, |y|, |width| and |height| are the position and dimensions of
    // a rectangle whose pixel values will be transfered to the host.
    // |pixels| is the address of a caller-provided buffer that will be filled
    // with the pixel data.
    // |pixles_size| is the size of buffer
    void readColorBufferYUV(HandleType p_colorbuffer, int x, int y, int width,
                            int height, void* pixels, uint32_t pixels_size);

    // create a Y texture and a UV texture with width and height, the created
    // texture ids are stored in textures respectively
    void createYUVTextures(uint32_t type, uint32_t count, int width, int height,
                           uint32_t* output);
    void destroyYUVTextures(uint32_t type, uint32_t count, uint32_t* textures);
    void updateYUVTextures(uint32_t type, uint32_t* textures, void* privData,
                           void* func);
    void swapTexturesAndUpdateColorBuffer(uint32_t colorbufferhandle, int x, int y, int width,
                                          int height, uint32_t format, uint32_t type,
                                          uint32_t texture_type, uint32_t* textures);

    // Update the content of a given Buffer from client data.
    // |p_buffer| is the Buffer's handle value.
    // |offset| and |size| are the position and size of a slice of the buffer
    // that will be updated.
    // |bytes| is the address of a caller-provided buffer containing the new
    // buffer data.
    bool updateBuffer(HandleType p_buffer, uint64_t offset, uint64_t size, void* pixels);

    // Update the content of a given ColorBuffer from client data.
    // |p_colorbuffer| is the ColorBuffer's handle value. Similar
    // to glReadPixels(), this can be a slow operation.
    // |x|, |y|, |width| and |height| are the position and dimensions of
    // a rectangle whose pixel values will be transfered to the GPU
    // |format| indicates the format of the OpenGL buffer, e.g. GL_RGB or
    // GL_RGBA. |frameworkFormat| indicates the format of the pixel data; if
    // FRAMEWORK_FORMAT_GL_COMPATIBLE, |format| (OpenGL format) is used.
    // Otherwise, explicit conversion to |format| is needed.
    // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
    // |pixels| is the address of a buffer containing the new pixel data.
    // Returns true on success, false otherwise.
    bool updateColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
                           int height, GLenum format, GLenum type,
                           void* pixels);
    bool updateColorBufferFromFrameworkFormat(HandleType p_colorbuffer, int x, int y, int width,
                                              int height, FrameworkFormat fwkFormat, GLenum format,
                                              GLenum type, void* pixels, void* metadata = nullptr);

    // Reads back the raw color buffer to |pixels|
    // if |pixels| is not null.
    // Always returns in |numBytes| how many bytes were
    // planned to be transmitted.
    // |numBytes| is not an input parameter;
    // fewer or more bytes cannot be specified.
    // If the framework format is YUV, it will read
    // back as raw YUV data.
    bool readColorBufferContents(HandleType p_colorbuffer, size_t* numBytes,
                                 void* pixels);

    bool getColorBufferInfo(HandleType p_colorbuffer, int* width, int* height,
                            GLint* internalformat,
                            FrameworkFormat* frameworkFormat = nullptr);
    bool getBufferInfo(HandleType p_buffer, int* size);

    // Display the content of a given ColorBuffer into the framebuffer's
    // sub-window. |p_colorbuffer| is a handle value.
    // |needLockAndBind| is used to indicate whether the operation requires
    // acquiring/releasing the FrameBuffer instance's lock and binding the
    // contexts. It should be |false| only when called internally.
    bool post(HandleType p_colorbuffer, bool needLockAndBind = true);
    // The callback will always be called; however, the callback may not be called
    // until after this function has returned. If the callback is deferred, then it
    // will be dispatched to run on SyncThread.
    void postWithCallback(HandleType p_colorbuffer, Post::CompletionCallback callback, bool needLockAndBind = true);
    bool hasGuestPostedAFrame() { return m_guestPostedAFrame; }
    void resetGuestPostedAFrame() { m_guestPostedAFrame = false; }

    // Runs the post callback with |pixels| (good for when the readback
    // happens in a separate place)
    void doPostCallback(void* pixels, uint32_t displayId);

    void getPixels(void* pixels, uint32_t bytes, uint32_t displayId);
    void flushReadPipeline(int displayId);
    void ensureReadbackWorker();

    bool asyncReadbackSupported();
    Renderer::ReadPixelsCallback getReadPixelsCallback();
    Renderer::FlushReadPixelPipeline getFlushReadPixelPipeline();

    // Re-post the last ColorBuffer that was displayed through post().
    // This is useful if you detect that the sub-window content needs to
    // be re-displayed for any reason.
    bool repost(bool needLockAndBind = true);

    gl::EmulationGl& getEmulationGl();
    bool hasEmulationGl() const { return m_emulationGl != nullptr; }

    // Return the host EGLDisplay used by this instance.
    EGLDisplay getDisplay() const;
    EGLSurface getWindowSurface() const;
    EGLContext getContext() const;
    EGLConfig getConfig() const;
    ContextHelper* getPbufferSurfaceContextHelper() const;

    // Change the rotation of the displayed GPU sub-window.
    void setDisplayRotation(float zRot) {
        if (zRot != m_zRot) {
            m_zRot = zRot;
            repost();
        }
    }

    // Changes what coordinate of this framebuffer will be displayed at the
    // corner of the GPU sub-window. Specifically, |px| and |py| = 0 means
    // align the bottom-left of the framebuffer with the bottom-left of the
    // sub-window, and |px| and |py| = 1 means align the top right of the
    // framebuffer with the top right of the sub-window. Intermediate values
    // interpolate between these states.
    void setDisplayTranslation(float px, float py) {
        // Sanity check the values to ensure they are between 0 and 1
        const float x = px > 1.f ? 1.f : (px < 0.f ? 0.f : px);
        const float y = py > 1.f ? 1.f : (py < 0.f ? 0.f : py);
        if (x != m_px || y != m_py) {
            m_px = x;
            m_py = y;
            repost();
        }
    }

    // Return a TextureDraw instance that can be used with this surfaces
    // and windows created by this instance.
    gl::TextureDraw* getTextureDraw() const;

    // Create an eglImage and return its handle.  Reference:
    // https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt
    HandleType createEmulatedEglImage(HandleType context, EGLenum target,
                                      GLuint buffer);
    // Call the implementation of eglDestroyImageKHR, return if succeeds or
    // not. Reference:
    // https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt
    EGLBoolean destroyEmulatedEglImage(HandleType image);

    void lockContextStructureRead() { m_contextStructureLock.lockRead(); }
    void unlockContextStructureRead() { m_contextStructureLock.unlockRead(); }

    // For use with sync threads and otherwise, any time we need a GL context
    // not specifically for drawing, but to obtain certain things about
    // GL state.
    // It can be unsafe / leaky to change the structure of contexts
    // outside the facilities the FrameBuffer class provides.
    void createTrivialContext(HandleType shared, HandleType* contextOut,
                              HandleType* surfOut);
    // createTrivialContext(), but with a m_pbufContext
    // as shared, and not adding itself to the context map at all.
    void createSharedTrivialContext(EGLContext* contextOut, EGLSurface* surfOut);
    void destroySharedTrivialContext(EGLContext context, EGLSurface surf);

    void setShuttingDown() { m_shuttingDown = true; }
    bool isShuttingDown() const { return m_shuttingDown; }
    bool compose(uint32_t bufferSize, void* buffer, bool post = true);
    // When false is returned, the callback won't be called. The callback will
    // be called on the PostWorker thread without blocking the current thread.
    AsyncResult composeWithCallback(uint32_t bufferSize, void* buffer,
                             Post::CompletionCallback callback);

    ~FrameBuffer();

    void onSave(android::base::Stream* stream,
                const android::snapshot::ITextureSaverPtr& textureSaver);
    bool onLoad(android::base::Stream* stream,
                const android::snapshot::ITextureLoaderPtr& textureLoader);

    // lock and unlock handles (EmulatedEglContext, ColorBuffer, EmulatedEglWindowSurface)
    void lock();
    void unlock();

    gl::GLESDispatchMaxVersion getMaxGLESVersion();

    float getDpr() const { return m_dpr; }
    int windowWidth() const { return m_windowWidth; }
    int windowHeight() const { return m_windowHeight; }
    float getPx() const { return m_px; }
    float getPy() const { return m_py; }
    int getZrot() const { return m_zRot; }

    bool isFastBlitSupported() const;
    void disableFastBlitForTesting();

    bool isVulkanInteropSupported() const { return m_vulkanInteropSupported; }
    bool isVulkanEnabled() const { return m_vulkanEnabled; }

    // Fill GLES usage protobuf
    void fillGLESUsages(android_studio::EmulatorGLESUsages*);

    // Saves a screenshot of the previous frame.
    // nChannels should be 3 (RGB) or 4 (RGBA).
    // You must provide a pre-allocated buffer of sufficient
    // size. Returns 0 on success. In the case of failure and if *cPixels != 0
    // you can call this function again with a buffer of size *cPixels. cPixels
    // should usually be at at least desiredWidth * desiredHeight * nChannels.
    //
    // In practice the buffer should be > desiredWidth *
    // desiredHeight * nChannels.
    //
    // Note: Do not call this function again if it fails and *cPixels == 0
    //  swiftshader_indirect does not work with 3 channels
    //
    // This function supports rectangle snipping by
    // providing an |rect| parameter. The default value of {{0,0}, {0,0}}
    // indicates the users wants to snip the entire screen instead of a
    // partial screen.
    // - |rect|  represents a rectangle within the screen defined by
    // desiredWidth and desiredHeight.
    int getScreenshot(unsigned int nChannels, unsigned int* width, unsigned int* height,
                      uint8_t* pixels, size_t* cPixels, int displayId, int desiredWidth,
                      int desiredHeight, int desiredRotation, Rect rect = {{0, 0}, {0, 0}});

    void onLastColorBufferRef(uint32_t handle);
    ColorBufferPtr findColorBuffer(HandleType p_colorbuffer);
    BufferPtr findBuffer(HandleType p_buffer);

    void registerProcessCleanupCallback(void* key,
                                        std::function<void()> callback);
    void unregisterProcessCleanupCallback(void* key);

    const ProcessResources* getProcessResources(uint64_t puid);

    int createDisplay(uint32_t *displayId);
    int createDisplay(uint32_t displayId);
    int destroyDisplay(uint32_t displayId);
    int setDisplayColorBuffer(uint32_t displayId, uint32_t colorBuffer);
    int getDisplayColorBuffer(uint32_t displayId, uint32_t* colorBuffer);
    int getColorBufferDisplay(uint32_t colorBuffer, uint32_t* displayId);
    int getDisplayPose(uint32_t displayId, int32_t* x, int32_t* y, uint32_t* w,
                       uint32_t* h);
    int setDisplayPose(uint32_t displayId, int32_t x, int32_t y, uint32_t w,
                       uint32_t h, uint32_t dpi = 0);
    void getCombinedDisplaySize(int* w, int* h);
    struct DisplayInfo {
        uint32_t cb;
        int32_t pos_x;
        int32_t pos_y;
        uint32_t width;
        uint32_t height;
        uint32_t dpi;
        DisplayInfo()
            : cb(0), pos_x(0), pos_y(0), width(0), height(0), dpi(0){};
        DisplayInfo(uint32_t cb, int32_t x, int32_t y, uint32_t w, uint32_t h,
                    uint32_t d)
            : cb(cb), pos_x(x), pos_y(y), width(w), height(h), dpi(d) {}
    };
    // Inline with MultiDisplay::s_invalidIdMultiDisplay
    static const uint32_t s_invalidIdMultiDisplay = 0xFFFFFFAB;
    static const uint32_t s_maxNumMultiDisplay = 11;

    EGLContext getGlobalEGLContext() const;
    HandleType getLastPostedColorBuffer() { return m_lastPostedColorBuffer; }
    void waitForGpu(uint64_t eglsync);
    void waitForGpuVulkan(uint64_t deviceHandle, uint64_t fenceHandle);
    void asyncWaitForGpuWithCb(uint64_t eglsync, FenceCompletionCallback cb);
    void asyncWaitForGpuVulkanWithCb(uint64_t deviceHandle, uint64_t fenceHandle, FenceCompletionCallback cb);
    void asyncWaitForGpuVulkanQsriWithCb(uint64_t image, FenceCompletionCallback cb);
    void waitForGpuVulkanQsri(uint64_t image);

    bool platformImportResource(uint32_t handle, uint32_t info, void* resource);
    void* platformCreateSharedEglContext(void);
    bool platformDestroySharedEglContext(void* context);

    void setGuestManagedColorBufferLifetime(bool guestManaged);

    std::unique_ptr<BorrowedImageInfo> borrowColorBufferForComposition(uint32_t colorBufferHandle,
                                                                       bool colorBufferIsTarget);
    std::unique_ptr<BorrowedImageInfo> borrowColorBufferForDisplay(uint32_t colorBufferHandle);

    HealthMonitor<>* getHealthMonitor() { return m_healthMonitor.get(); }

    emugl::MetricsLogger& getMetricsLogger() {
        return *m_logger;
    }

    void logVulkanOutOfMemory(VkResult result, const char* function, int line,
                              std::optional<uint64_t> allocationSize = std::nullopt);

    void setVsyncHz(int vsyncHz);
    void scheduleVsyncTask(VsyncThread::VsyncTask task);
    void setDisplayConfigs(int configId, int w, int h, int dpiX, int dpiY);
    void setDisplayActiveConfig(int configId);
    const int getDisplayConfigsCount();
    const int getDisplayConfigsParam(int configId, EGLint param);
    const int getDisplayActiveConfig();

    bool flushColorBufferFromGl(HandleType colorBufferHandle);
    bool flushColorBufferFromGlLocked(HandleType colorBufferHandle);
    bool flushColorBufferFromVk(HandleType colorBufferHandle);
    bool flushColorBufferFromVkBytes(HandleType colorBufferHandle, const void* bytes, size_t bytesSize);
    bool invalidateColorBufferForGl(HandleType colorBufferHandle);
    bool invalidateColorBufferForVk(HandleType colorBufferHandle);

    const gl::EGLDispatch* getEglDispatch();
    const gl::GLESv2Dispatch* getGles2Dispatch();

   private:
    FrameBuffer(int p_width, int p_height, bool useSubWindow);
    // Requires the caller to hold the m_colorBufferMapLock until the new handle is inserted into of
    // the object handle maps.
    HandleType genHandle_locked();

    bool removeSubWindow_locked();
    // Returns the set of ColorBuffers destroyed (for further cleanup)
    std::vector<HandleType> cleanupProcGLObjects_locked(uint64_t puid,
                                                        bool forced = false);

    void markOpened(ColorBufferRef* cbRef);
    // Returns true if the color buffer was erased.
    bool closeColorBufferLocked(HandleType p_colorbuffer, bool forced = false);
    // Returns true if this was the last ref and we need to destroy stuff.
    bool decColorBufferRefCountLocked(HandleType p_colorbuffer);
    // Decrease refcount but not destroy the object.
    // Mainly used in post thread, when we need to destroy the object but cannot in post thread.
    void decColorBufferRefCountNoDestroy(HandleType p_colorbuffer);
    // Close all expired color buffers for real.
    // Treat all delayed color buffers as expired if forced=true
    void performDelayedColorBufferCloseLocked(bool forced = false);
    void eraseDelayedCloseColorBufferLocked(HandleType cb, uint64_t ts);

    AsyncResult postImpl(HandleType p_colorbuffer, Post::CompletionCallback callback,
                  bool needLockAndBind = true, bool repaint = false);
    bool postImplSync(HandleType p_colorbuffer, bool needLockAndBind = true, bool repaint = false);
    void setGuestPostedAFrame() {
        m_guestPostedAFrame = true;
        fireEvent({FrameBufferChange::FrameReady, mFrameNumber++});
    }
    HandleType createColorBufferWithHandleLocked(int p_width, int p_height, GLenum p_internalFormat,
                                                 FrameworkFormat p_frameworkFormat,
                                                 HandleType handle);
    HandleType createBufferWithHandleLocked(int p_size, HandleType handle, uint32_t memoryProperty);

    void recomputeLayout();
    void setDisplayPoseInSkinUI(int totalHeight);
    void sweepColorBuffersLocked();

    std::future<void> blockPostWorker(std::future<void> continueSignal);

   private:

    static FrameBuffer* s_theFrameBuffer;
    static HandleType s_nextHandle;
    int m_x = 0;
    int m_y = 0;
    int m_framebufferWidth = 0;
    int m_framebufferHeight = 0;
    std::atomic_int m_windowWidth = 0;
    std::atomic_int m_windowHeight = 0;
    // When zoomed in, the size of the content is bigger than the window size, and we only
    // display / store a portion of it.
    int m_windowContentFullWidth = 0;
    int m_windowContentFullHeight = 0;
    float m_dpr = 0;

    bool m_useSubWindow = false;

    bool m_fpsStats = false;
    bool m_perfStats = false;
    int m_statsNumFrames = 0;
    long long m_statsStartTime = 0;

    android::base::Thread* m_perfThread;
    android::base::Lock m_lock;
    android::base::ReadWriteLock m_contextStructureLock;
    android::base::Lock m_colorBufferMapLock;
    uint64_t mFrameNumber;
    FBNativeWindowType m_nativeWindow = 0;
    gl::EmulatedEglContextMap m_contexts;
    gl::EmulatedEglImageMap m_images;
    gl::EmulatedEglWindowSurfaceMap m_windows;
    ColorBufferMap m_colorbuffers;
    BufferMap m_buffers;
    std::unordered_map<HandleType, HandleType> m_EmulatedEglWindowSurfaceToColorBuffer;

    // A collection of color buffers that were closed without any usages
    // (|opened| == false).
    //
    // If a buffer reached |refcount| == 0 while not being |opened|, instead of
    // deleting it we remember the timestamp when this happened. Later, we
    // check if the buffer stayed unopened long enough and if it did, we delete
    // it permanently. On the other hand, if the color buffer was used then
    // we don't care about timestamps anymore.
    //
    // Note: this collection is ordered by |ts| field.
    struct ColorBufferCloseInfo {
        uint64_t ts;          // when we got the close request.
        HandleType cbHandle;  // 0 == already closed, do nothing
    };
    using ColorBufferDelayedClose = std::vector<ColorBufferCloseInfo>;
    ColorBufferDelayedClose m_colorBufferDelayedCloseList;

    EGLNativeWindowType m_subWin = {};
    HandleType m_lastPostedColorBuffer = 0;
    float m_zRot = 0;
    float m_px = 0;
    float m_py = 0;

    // Async readback
    enum class ReadbackCmd {
        Init = 0,
        GetPixels = 1,
        AddRecordDisplay = 2,
        DelRecordDisplay = 3,
        Exit = 4,
    };
    struct Readback {
        ReadbackCmd cmd;
        uint32_t displayId;
        void* pixelsOut;
        uint32_t bytes;
        uint32_t width;
        uint32_t height;
    };
    android::base::WorkerProcessingResult sendReadbackWorkerCmd(
        const Readback& readback);
    bool m_guestPostedAFrame = false;

    struct onPost {
        Renderer::OnPostCallback cb;
        void* context;
        uint32_t displayId;
        uint32_t width;
        uint32_t height;
        unsigned char* img = nullptr;
        bool readBgra;
        ~onPost() {
            if (img) {
                delete[] img;
                img = nullptr;
            }
        }
    };
    std::map<uint32_t, onPost> m_onPost;
    ReadbackWorker* m_readbackWorker = nullptr;
    android::base::WorkerThread<Readback> m_readbackThread;
    std::atomic_bool m_readbackThreadStarted = false;

    std::string m_graphicsAdapterVendor;
    std::string m_graphicsAdapterName;
    std::string m_graphicsApiVersion;
    std::string m_graphicsApiExtensions;
    std::string m_graphicsDeviceExtensions;

    // The host associates color buffers with guest processes for memory
    // cleanup. Guest processes are identified with a host generated unique ID.
    // TODO(kaiyili): move all those resources to the ProcessResources struct.
    ProcOwnedColorBuffers m_procOwnedColorBuffers;
    ProcOwnedEmulatedEGLImages m_procOwnedEmulatedEglImages;
    ProcOwnedEmulatedEglContexts m_procOwnedEmulatedEglContexts;
    ProcOwnedEmulatedEglWindowSurfaces m_procOwnedEmulatedEglWindowSurfaces;
    ProcOwnedCleanupCallbacks m_procOwnedCleanupCallbacks;
    std::unordered_map<uint64_t, std::unique_ptr<ProcessResources>> m_procOwnedResources;

    // Flag set when emulator is shutting down.
    bool m_shuttingDown = false;

    // When this feature is enabled, open/close operations from gralloc in guest
    // will no longer control the reference counting of color buffers on host.
    // Instead, it will be managed by a file descriptor in the guest kernel. In
    // case all the native handles in guest are destroyed, the pipe will be
    // automatically closed by the kernel. We only need to do reference counting
    // for color buffers attached in window surface.
    bool m_refCountPipeEnabled = false;

    // When this feature is enabled, and m_refCountPipeEnabled == false, color
    // buffer close operations will immediately close the color buffer if host
    // refcount hits 0. This is for use with guest kernels where the color
    // buffer is already tied to a file descriptor in the guest kernel.
    bool m_noDelayCloseColorBufferEnabled = false;

    std::unique_ptr<PostWorker> m_postWorker = {};
    std::atomic_bool m_postThreadStarted = false;
    android::base::WorkerThread<Post> m_postThread;
    android::base::WorkerProcessingResult postWorkerFunc(Post& post);
    std::future<void> sendPostWorkerCmd(Post post);

    bool m_vulkanInteropSupported = false;
    bool m_vulkanEnabled = false;
    bool m_guestUsesAngle = false;
    // Whether the guest manages ColorBuffer lifetime
    // so we don't need refcounting on the host side.
    bool m_guestManagedColorBufferLifetime = false;

    android::base::MessageChannel<HandleType, 1024>
        mOutstandingColorBufferDestroys;

    std::unique_ptr<gl::EmulationGl> m_emulationGl;
    gl::DisplayGl* m_displayGl = nullptr;

    Compositor* m_compositor = nullptr;
    bool m_useVulkanComposition = false;

    vk::VkEmulation* m_emulationVk = nullptr;
    // The implementation for Vulkan native swapchain. Only initialized when useVulkan is set when
    // calling FrameBuffer::initialize(). DisplayVk is actually owned by VkEmulation.
    vk::DisplayVk* m_displayVk = nullptr;
    VkInstance m_vkInstance = VK_NULL_HANDLE;
    std::unique_ptr<emugl::RenderDoc> m_renderDoc = nullptr;

    // TODO(b/233939967): Refactor to create DisplayGl and DisplaySurfaceGl
    // and remove usage of non-generic DisplayVk.
    Display* m_display;
    std::unique_ptr<DisplaySurface> m_displaySurface;

    // CompositorGl.
    // TODO: update RenderDoc to be a DisplaySurfaceUser.
    std::vector<DisplaySurfaceUser*> m_displaySurfaceUsers;

    // UUIDs of physical devices for Vulkan and GLES, respectively.  In most
    // cases, this determines whether we can support zero-copy interop.
    using VkUuid = std::array<uint8_t, VK_UUID_SIZE>;
    VkUuid m_vulkanUUID{};
    static_assert(VK_UUID_SIZE == GL_UUID_SIZE_EXT);

    // Tracks platform EGL contexts that have been handed out to other users,
    // indexed by underlying native EGL context object.
    struct PlatformEglContextInfo {
        EGLContext context;
        EGLSurface surface;
    };
    std::unordered_map<void*, PlatformEglContextInfo> m_platformEglContexts;

    std::unique_ptr<MetricsLogger> m_logger;
    std::unique_ptr<HealthMonitor<>> m_healthMonitor;

    int m_vsyncHz = 60;

    // Vsync thread.
    std::unique_ptr<VsyncThread> m_vsyncThread = {};

    struct DisplayConfig{
        int w;
        int h;
        int dpiX;
        int dpiY;
        DisplayConfig() {}
        DisplayConfig(int w, int h, int x, int y)
        : w(w), h(h), dpiX(x), dpiY(y) {}
    };
    std::map<int, DisplayConfig> mDisplayConfigs;
    int mDisplayActiveConfigId = -1;
};

}  // namespace gfxstream

#endif
