/*
 * 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_GRADIENT_CACHE_H
#define ANDROID_HWUI_GRADIENT_CACHE_H

#include <memory>

#include <GLES3/gl3.h>

#include <SkShader.h>

#include <utils/LruCache.h>
#include <utils/Mutex.h>

#include "FloatColor.h"

namespace android {
namespace uirenderer {

class Texture;

struct GradientCacheEntry {
    GradientCacheEntry() {
        count = 0;
        colors = nullptr;
        positions = nullptr;
    }

    GradientCacheEntry(uint32_t* colors, float* positions, uint32_t count) {
        copy(colors, positions, count);
    }

    GradientCacheEntry(const GradientCacheEntry& entry) {
        copy(entry.colors.get(), entry.positions.get(), entry.count);
    }

    GradientCacheEntry& operator=(const GradientCacheEntry& entry) {
        if (this != &entry) {
            copy(entry.colors.get(), entry.positions.get(), entry.count);
        }

        return *this;
    }

    hash_t hash() const;

    static int compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs);

    bool operator==(const GradientCacheEntry& other) const {
        return compare(*this, other) == 0;
    }

    bool operator!=(const GradientCacheEntry& other) const {
        return compare(*this, other) != 0;
    }

    std::unique_ptr<uint32_t[]> colors;
    std::unique_ptr<float[]> positions;
    uint32_t count;

private:
    void copy(uint32_t* colors, float* positions, uint32_t count) {
        this->count = count;
        this->colors.reset(new uint32_t[count]);
        this->positions.reset(new float[count]);

        memcpy(this->colors.get(), colors, count * sizeof(uint32_t));
        memcpy(this->positions.get(), positions, count * sizeof(float));
    }

}; // GradientCacheEntry

// Caching support

inline int strictly_order_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
    return GradientCacheEntry::compare(lhs, rhs) < 0;
}

inline int compare_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
    return GradientCacheEntry::compare(lhs, rhs);
}

inline hash_t hash_type(const GradientCacheEntry& entry) {
    return entry.hash();
}

/**
 * A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
 * Any texture added to the cache causing the cache to grow beyond the maximum
 * allowed size will also cause the oldest texture to be kicked out.
 */
class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> {
public:
    explicit GradientCache(Extensions& extensions);
    ~GradientCache();

    /**
     * Used as a callback when an entry is removed from the cache.
     * Do not invoke directly.
     */
    void operator()(GradientCacheEntry& shader, Texture*& texture) override;

    /**
     * Returns the texture associated with the specified shader.
     */
    Texture* get(uint32_t* colors, float* positions, int count);

    /**
     * Clears the cache. This causes all textures to be deleted.
     */
    void clear();

    /**
     * Returns the maximum size of the cache in bytes.
     */
    uint32_t getMaxSize();
    /**
     * Returns the current size of the cache in bytes.
     */
    uint32_t getSize();

private:
    /**
     * Adds a new linear gradient to the cache. The generated texture is
     * returned.
     */
    Texture* addLinearGradient(GradientCacheEntry& gradient,
            uint32_t* colors, float* positions, int count);

    void generateTexture(uint32_t* colors, float* positions,
            const uint32_t width, const uint32_t height, Texture* texture);

    struct GradientInfo {
        uint32_t width;
        bool hasAlpha;
    };

    void getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info);

    size_t bytesPerPixel() const;
    size_t sourceBytesPerPixel() const;

    typedef void (GradientCache::*ChannelMixer)(const FloatColor& start, const FloatColor& end,
            float amount, uint8_t*& dst) const;

    void mixBytes(const FloatColor& start, const FloatColor& end,
            float amount, uint8_t*& dst) const;
    void mixFloats(const FloatColor& start, const FloatColor& end,
            float amount, uint8_t*& dst) const;

    LruCache<GradientCacheEntry, Texture*> mCache;

    uint32_t mSize;
    const uint32_t mMaxSize;

    GLint mMaxTextureSize;
    bool mUseFloatTexture;
    bool mHasNpot;
    bool mHasLinearBlending;

    mutable Mutex mLock;
}; // class GradientCache

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

#endif // ANDROID_HWUI_GRADIENT_CACHE_H
