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

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include "emugl/common/smart_ptr.h"

#include <memory>


class TextureDraw;
class TextureResize;

// A class used to model a guest color buffer, and used to implement several
// related things:
//
//  - Every gralloc native buffer with HW read or write requirements will
//    allocate a host ColorBuffer instance. When gralloc_lock() is called,
//    the guest will use ColorBuffer::readPixels() to read the current content
//    of the buffer. When gralloc_unlock() is later called, it will call
//    ColorBuffer::subUpdate() to send the updated pixels.
//
//  - Every guest window EGLSurface is implemented by a host PBuffer
//    (see WindowSurface.h) that can have a ColorBuffer instance attached to
//    it (through WindowSurface::attachColorBuffer()). When such an attachment
//    exists, WindowSurface::flushColorBuffer() will copy the PBuffer's
//    pixel data into the ColorBuffer. The latter can then be displayed
//    in the client's UI sub-window with ColorBuffer::post().
//
//  - Guest EGLImages are implemented as native gralloc buffers too.
//    The guest glEGLImageTargetTexture2DOES() implementations will end up
//    calling ColorBuffer::bindToTexture() to bind the current context's
//    GL_TEXTURE_2D to the buffer. Similarly, the guest versions of
//    glEGLImageTargetRenderbufferStorageOES() will end up calling
//    ColorBuffer::bindToRenderbuffer().
//
// This forces the implementation to use a host EGLImage to implement each
// ColorBuffer.
//
// As an additional twist.

class ColorBuffer {
public:
    // Helper interface class used during ColorBuffer operations. This is
    // introduced to remove coupling from the FrameBuffer class implementation.
    class Helper {
    public:
        Helper() {}
        virtual ~Helper() {}
        virtual bool setupContext() = 0;
        virtual void teardownContext() = 0;
        virtual TextureDraw* getTextureDraw() const = 0;
    };

    // Create a new ColorBuffer instance.
    // |p_display| is the host EGLDisplay handle.
    // |p_width| and |p_height| are the buffer's dimensions in pixels.
    // |p_internalFormat| is the internal pixel format to use, valid values
    // are: GL_RGB, GL_RGB565, GL_RGBA, GL_RGB5_A1_OES and GL_RGBA4_OES.
    // Implementation is free to use something else though.
    // |has_eglimage_texture_2d| should be true iff the display supports
    // the EGL_KHR_gl_texture_2D_image extension.
    // Returns NULL on failure.
    static ColorBuffer* create(EGLDisplay p_display,
                               int p_width,
                               int p_height,
                               GLenum p_internalFormat,
                               bool has_eglimage_texture_2d,
                               Helper* helper);

    // Destructor.
    ~ColorBuffer();

    // Return ColorBuffer width and height in pixels
    GLuint getWidth() const { return m_width; }
    GLuint getHeight() const { return m_height; }

    // Read the ColorBuffer instance's pixel values into host memory.
    void readPixels(int x,
                    int y,
                    int width,
                    int height,
                    GLenum p_format,
                    GLenum p_type,
                    void *pixels);

    // Update the ColorBuffer instance's pixel values from host memory.
    void subUpdate(int x,
                   int y,
                   int width,
                   int height,
                   GLenum p_format,
                   GLenum p_type,
                   void *pixels);

    // Draw a ColorBuffer instance, i.e. blit it to the current guest
    // framebuffer object / window surface. This doesn't display anything.
    bool draw();

    // Post this ColorBuffer to the host native sub-window.
    // |rotation| is the rotation angle in degrees, clockwise in the GL
    // coordinate space.
    bool post(float rotation, float dx, float dy);

    // Bind the current context's EGL_TEXTURE_2D texture to this ColorBuffer's
    // EGLImage. This is intended to implement glEGLImageTargetTexture2DOES()
    // for all GLES versions.
    bool bindToTexture();

    // 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.
    bool bindToRenderbuffer();

    // Copy the content of the current context's read surface to this
    // ColorBuffer. This is used from WindowSurface::flushColorBuffer().
    // Return true on success, false on failure (e.g. no current context).
    bool blitFromCurrentReadBuffer();

    // Read the content of the whole ColorBuffer as 32-bit RGBA pixels.
    // |img| must be a buffer large enough (i.e. width * height * 4).
    void readback(unsigned char* img);

private:
    ColorBuffer(EGLDisplay display, Helper* helper);

private:
    GLuint m_tex = 0;
    GLuint m_blitTex = 0;
    EGLImageKHR m_eglImage = nullptr;
    EGLImageKHR m_blitEGLImage = nullptr;
    GLuint m_width = 0;
    GLuint m_height = 0;
    GLuint m_fbo = 0;
    GLenum m_internalFormat = 0;
    EGLDisplay m_display = nullptr;
    Helper* m_helper = nullptr;
    TextureResize* m_resizer = nullptr;
};

typedef emugl::SmartPtr<ColorBuffer> ColorBufferPtr;

#endif
