/*
 * Copyright (C) 2010 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_TEXTURE_H
#define ANDROID_HWUI_TEXTURE_H

#include "GpuMemoryTracker.h"
#include "hwui/Bitmap.h"
#include "utils/Color.h"

#include <memory>

#include <math/mat3.h>

#include <ui/ColorSpace.h>

#include <GLES2/gl2.h>
#include <GLES3/gl3.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <SkBitmap.h>

namespace android {

class GraphicBuffer;

namespace uirenderer {

class Caches;
class UvMapper;
class Layer;

/**
 * Represents an OpenGL texture.
 */
class Texture : public GpuMemoryTracker {
public:
    static SkBitmap uploadToN32(const SkBitmap& bitmap,
            bool hasLinearBlending, sk_sp<SkColorSpace> sRGB);
    static bool hasUnsupportedColorType(const SkImageInfo& info, bool hasLinearBlending);
    static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType,
            bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType);

    explicit Texture(Caches& caches)
        : GpuMemoryTracker(GpuObjectType::Texture)
        , mCaches(caches)
    { }

    virtual ~Texture() { }

    inline void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
        setWrapST(wrap, wrap, bindTexture, force);
    }

    virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
            bool force = false);

    inline void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
        setFilterMinMag(filter, filter, bindTexture, force);
    }

    virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
            bool force = false);

    /**
     * Convenience method to call glDeleteTextures() on this texture's id.
     */
    void deleteTexture();

    /**
     * Sets the width, height, and format of the texture along with allocating
     * the texture ID. Does nothing if the width, height, and format are already
     * the requested values.
     *
     * The image data is undefined after calling this.
     */
    void resize(uint32_t width, uint32_t height, GLint internalFormat, GLint format) {
        upload(internalFormat, width, height, format,
                internalFormat == GL_RGBA16F ? GL_HALF_FLOAT : GL_UNSIGNED_BYTE, nullptr);
    }

    /**
     * Updates this Texture with the contents of the provided Bitmap,
     * also setting the appropriate width, height, and format. It is not necessary
     * to call resize() prior to this.
     *
     * Note this does not set the generation from the Bitmap.
     */
    void upload(Bitmap& source);

    /**
     * Basically glTexImage2D/glTexSubImage2D.
     */
    void upload(GLint internalFormat, uint32_t width, uint32_t height,
            GLenum format, GLenum type, const void* pixels);

    /**
     * Wraps an existing texture.
     */
    void wrap(GLuint id, uint32_t width, uint32_t height, GLint internalFormat,
            GLint format, GLenum target);

    GLuint id() const {
        return mId;
    }

    uint32_t width() const {
        return mWidth;
    }

    uint32_t height() const {
        return mHeight;
    }

    GLint format() const {
        return mFormat;
    }

    GLint internalFormat() const {
        return mInternalFormat;
    }

    GLenum target() const {
        return mTarget;
    }

    /**
     * Returns nullptr if this texture does not require color space conversion
     * to sRGB, or a valid pointer to a ColorSpaceConnector if a conversion
     * is required.
     */
    constexpr const ColorSpaceConnector* getColorSpaceConnector() const {
        return mConnector.get();
    }

    constexpr bool hasColorSpaceConversion() const {
        return mConnector.get() != nullptr;
    }

    TransferFunctionType getTransferFunctionType() const;

    /**
     * Returns true if this texture uses a linear encoding format.
     */
    constexpr bool isLinear() const {
        return mIsLinear;
    }

    /**
     * Generation of the backing bitmap,
     */
    uint32_t generation = 0;
    /**
     * Indicates whether the texture requires blending.
     */
    bool blend = false;
    /**
     * Indicates whether this texture should be cleaned up after use.
     */
    bool cleanup = false;
    /**
     * Optional, size of the original bitmap.
     */
    uint32_t bitmapSize = 0;
    /**
     * Indicates whether this texture will use trilinear filtering.
     */
    bool mipMap = false;

    /**
     * Optional, pointer to a texture coordinates mapper.
     */
    const UvMapper* uvMapper = nullptr;

    /**
     * Whether or not the Texture is marked in use and thus not evictable for
     * the current frame. This is reset at the start of a new frame.
     */
    void* isInUse = nullptr;
private:
    // TODO: Temporarily grant private access to GlLayer, remove once
    // GlLayer can be de-tangled from being a dual-purpose render target
    // and external texture wrapper
    friend class GlLayer;

    // Returns true if the texture layout (size, format, etc.) changed, false if it was the same
    bool updateLayout(uint32_t width, uint32_t height, GLint internalFormat,
            GLint format, GLenum target);
    void uploadHardwareBitmapToTexture(GraphicBuffer* buffer);
    void resetCachedParams();

    GLuint mId = 0;
    uint32_t mWidth = 0;
    uint32_t mHeight = 0;
    GLint mFormat = 0;
    GLint mInternalFormat = 0;
    GLenum mTarget = GL_NONE;
    EGLImageKHR mEglImageHandle = EGL_NO_IMAGE_KHR;

    /* See GLES spec section 3.8.14
     * "In the initial state, the value assigned to TEXTURE_MIN_FILTER is
     * NEAREST_MIPMAP_LINEAR and the value for TEXTURE_MAG_FILTER is LINEAR.
     * s, t, and r wrap modes are all set to REPEAT."
     */
    GLenum mWrapS = GL_REPEAT;
    GLenum mWrapT = GL_REPEAT;
    GLenum mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
    GLenum mMagFilter = GL_LINEAR;

    // Indicates whether the content of the texture is in linear space
    bool mIsLinear = false;

    Caches& mCaches;

    std::unique_ptr<ColorSpaceConnector> mConnector;
}; // struct Texture

class AutoTexture {
public:
    explicit AutoTexture(Texture* texture)
            : texture(texture) {}
    ~AutoTexture() {
        if (texture && texture->cleanup) {
            texture->deleteTexture();
            delete texture;
        }
    }

    Texture* const texture;
}; // class AutoTexture

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

#endif // ANDROID_HWUI_TEXTURE_H
