/*
 * Copyright (C) 2013 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 ANDROID_HWUI_PIXEL_BUFFER_H
#define ANDROID_HWUI_PIXEL_BUFFER_H

#include <GLES3/gl3.h>

namespace android {
namespace uirenderer {

/**
 * Represents a pixel buffer. A pixel buffer will be backed either by a
 * PBO on OpenGL ES 3.0 and higher or by an array of uint8_t on other
 * versions. If the buffer is backed by a PBO it will of type
 * GL_PIXEL_UNPACK_BUFFER.
 *
 * To read from or write into a PixelBuffer you must first map the
 * buffer using the map(AccessMode) method. This method returns a
 * pointer to the beginning of the buffer.
 *
 * Before the buffer can be used by the GPU, for instance to upload
 * a texture, you must first unmap the buffer. To do so, call the
 * unmap() method.
 *
 * Mapping and unmapping a PixelBuffer can have the side effect of
 * changing the currently active GL_PIXEL_UNPACK_BUFFER. It is
 * therefore recommended to call Caches::unbindPixelbuffer() after
 * using a PixelBuffer to upload to a texture.
 */
class PixelBuffer {
public:
    enum BufferType {
        kBufferType_Auto,
        kBufferType_CPU
    };

    enum AccessMode {
        kAccessMode_None = 0,
        kAccessMode_Read = GL_MAP_READ_BIT,
        kAccessMode_Write = GL_MAP_WRITE_BIT,
        kAccessMode_ReadWrite = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT
    };

    /**
     * Creates a new PixelBuffer object with the specified format and
     * dimensions. The buffer is immediately allocated.
     *
     * The buffer type specifies how the buffer should be allocated.
     * By default this method will automatically choose whether to allocate
     * a CPU or GPU buffer.
     */
    static PixelBuffer* create(GLenum format, uint32_t width, uint32_t height,
            BufferType type = kBufferType_Auto);

    virtual ~PixelBuffer() {
    }

    /**
     * Returns the format of this render buffer.
     */
    GLenum getFormat() const {
        return mFormat;
    }

    /**
     * Maps this before with the specified access mode. This method
     * returns a pointer to the region of memory where the buffer was
     * mapped.
     *
     * If the buffer is already mapped when this method is invoked,
     * this method will return the previously mapped pointer. The
     * access mode can only be changed by calling unmap() first.
     *
     * The specified access mode cannot be kAccessMode_None.
     */
    virtual uint8_t* map(AccessMode mode = kAccessMode_ReadWrite) = 0;

    /**
     * Unmaps this buffer, if needed. After the buffer is unmapped,
     * the pointer previously returned by map() becomes invalid and
     * should not be used. After calling this method, getMappedPointer()
     * will always return NULL.
     */
    virtual void unmap() = 0;

    /**
     * Returns the current access mode for this buffer. If the buffer
     * is not mapped, this method returns kAccessMode_None.
     */
    AccessMode getAccessMode() const {
        return mAccessMode;
    }

    /**
     * Returns the currently mapped pointer. Returns NULL if the buffer
     * is not mapped.
     */
    virtual uint8_t* getMappedPointer() const = 0;

    /**
     * Upload the specified rectangle of this pixe buffer as a
     * GL_TEXTURE_2D texture. Calling this method will trigger
     * an unmap() if necessary.
     */
    virtual void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) = 0;

    /**
     * Returns the width of the render buffer in pixels.
     */
    uint32_t getWidth() const {
        return mWidth;
    }

    /**
     * Returns the height of the render buffer in pixels.
     */
    uint32_t getHeight() const {
        return mHeight;
    }

    /**
     * Returns the size of this pixel buffer in bytes.
     */
    uint32_t getSize() const {
        return mWidth * mHeight * formatSize(mFormat);
    }

    /**
     * Returns the number of bytes per pixel in the specified format.
     *
     * Supported formats:
     *      GL_ALPHA
     *      GL_RGBA
     */
    static uint32_t formatSize(GLenum format) {
        switch (format) {
            case GL_ALPHA:
                return 1;
            case GL_RGBA:
                return 4;
        }
        return 0;
    }

protected:
    /**
     * Creates a new render buffer in the specified format and dimensions.
     * The format must be GL_ALPHA or GL_RGBA.
     */
    PixelBuffer(GLenum format, uint32_t width, uint32_t height):
            mFormat(format), mWidth(width), mHeight(height), mAccessMode(kAccessMode_None) {
    }

    GLenum mFormat;

    uint32_t mWidth;
    uint32_t mHeight;

    AccessMode mAccessMode;

}; // class PixelBuffer

}; // namespace uirenderer
}; // namespace android

#endif // ANDROID_HWUI_PIXEL_BUFFER_H
