/*
 * 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>

#include <log/log.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;

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

    /**
     * Upload the specified rectangle of this pixel 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;

    /**
     * Upload the specified rectangle of this pixel buffer as a
     * GL_TEXTURE_2D texture. Calling this method will trigger
     * an unmap() if necessary.
     *
     * This is a convenience function provided to save callers the
     * trouble of computing the offset parameter.
     */
    void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
        upload(x, y, width, height, getOffset(x, y));
    }

    /**
     * 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 offset of a pixel in this pixel buffer, in bytes.
     */
    uint32_t getOffset(uint32_t x, uint32_t y) const {
        return (y * mWidth + x) * 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;
    }

    /**
     * Returns the alpha channel offset in the specified format.
     *
     * Supported formats:
     *      GL_ALPHA
     *      GL_RGBA
     */
    static uint32_t formatAlphaOffset(GLenum format) {
        switch (format) {
            case GL_ALPHA:
                return 0;
            case GL_RGBA:
                return 3;
        }

        ALOGE("unsupported format: %d", format);
        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) {}

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

    GLenum mFormat;

    uint32_t mWidth;
    uint32_t mHeight;

    AccessMode mAccessMode;

};  // class PixelBuffer

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

#endif  // ANDROID_HWUI_PIXEL_BUFFER_H
