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

#include <utils/JenkinsHash.h>

#include "Caches.h"
#include "Debug.h"
#include "GradientCache.h"
#include "Properties.h"

#include <cutils/properties.h>

namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Functions
///////////////////////////////////////////////////////////////////////////////

template<typename T>
static inline T min(T a, T b) {
    return a < b ? a : b;
}

///////////////////////////////////////////////////////////////////////////////
// Cache entry
///////////////////////////////////////////////////////////////////////////////

hash_t GradientCacheEntry::hash() const {
    uint32_t hash = JenkinsHashMix(0, count);
    for (uint32_t i = 0; i < count; i++) {
        hash = JenkinsHashMix(hash, android::hash_type(colors[i]));
        hash = JenkinsHashMix(hash, android::hash_type(positions[i]));
    }
    return JenkinsHashWhiten(hash);
}

int GradientCacheEntry::compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
    int deltaInt = int(lhs.count) - int(rhs.count);
    if (deltaInt != 0) return deltaInt;

    deltaInt = memcmp(lhs.colors.get(), rhs.colors.get(), lhs.count * sizeof(uint32_t));
    if (deltaInt != 0) return deltaInt;

    return memcmp(lhs.positions.get(), rhs.positions.get(), lhs.count * sizeof(float));
}

///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////

GradientCache::GradientCache(Extensions& extensions)
        : mCache(LruCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity)
        , mSize(0)
        , mMaxSize(Properties::gradientCacheSize)
        , mUseFloatTexture(extensions.hasFloatTextures())
        , mHasNpot(extensions.hasNPot())
        , mHasLinearBlending(extensions.hasLinearBlending()) {
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);

    mCache.setOnEntryRemovedListener(this);
}

GradientCache::~GradientCache() {
    mCache.clear();
}

///////////////////////////////////////////////////////////////////////////////
// Size management
///////////////////////////////////////////////////////////////////////////////

uint32_t GradientCache::getSize() {
    return mSize;
}

uint32_t GradientCache::getMaxSize() {
    return mMaxSize;
}

///////////////////////////////////////////////////////////////////////////////
// Callbacks
///////////////////////////////////////////////////////////////////////////////

void GradientCache::operator()(GradientCacheEntry&, Texture*& texture) {
    if (texture) {
        mSize -= texture->objectSize();
        texture->deleteTexture();
        delete texture;
    }
}

///////////////////////////////////////////////////////////////////////////////
// Caching
///////////////////////////////////////////////////////////////////////////////

Texture* GradientCache::get(uint32_t* colors, float* positions, int count) {
    GradientCacheEntry gradient(colors, positions, count);
    Texture* texture = mCache.get(gradient);

    if (!texture) {
        texture = addLinearGradient(gradient, colors, positions, count);
    }

    return texture;
}

void GradientCache::clear() {
    mCache.clear();
}

void GradientCache::getGradientInfo(const uint32_t* colors, const int count,
        GradientInfo& info) {
    uint32_t width = 256 * (count - 1);

    // If the npot extension is not supported we cannot use non-clamp
    // wrap modes. We therefore find the nearest largest power of 2
    // unless width is already a power of 2
    if (!mHasNpot && (width & (width - 1)) != 0) {
        width = 1 << (32 - __builtin_clz(width));
    }

    bool hasAlpha = false;
    for (int i = 0; i < count; i++) {
        if (((colors[i] >> 24) & 0xff) < 255) {
            hasAlpha = true;
            break;
        }
    }

    info.width = min(width, uint32_t(mMaxTextureSize));
    info.hasAlpha = hasAlpha;
}

Texture* GradientCache::addLinearGradient(GradientCacheEntry& gradient,
        uint32_t* colors, float* positions, int count) {

    GradientInfo info;
    getGradientInfo(colors, count, info);

    Texture* texture = new Texture(Caches::getInstance());
    texture->blend = info.hasAlpha;
    texture->generation = 1;

    // Assume the cache is always big enough
    const uint32_t size = info.width * 2 * bytesPerPixel();
    while (getSize() + size > mMaxSize) {
        LOG_ALWAYS_FATAL_IF(!mCache.removeOldest(),
                "Ran out of things to remove from the cache? getSize() = %" PRIu32
                ", size = %" PRIu32 ", mMaxSize = %" PRIu32 ", width = %" PRIu32,
                getSize(), size, mMaxSize, info.width);
    }

    generateTexture(colors, positions, info.width, 2, texture);

    mSize += size;
    LOG_ALWAYS_FATAL_IF((int)size != texture->objectSize(),
            "size != texture->objectSize(), size %" PRIu32 ", objectSize %d"
            " width = %" PRIu32 " bytesPerPixel() = %zu",
            size, texture->objectSize(), info.width, bytesPerPixel());
    mCache.put(gradient, texture);

    return texture;
}

size_t GradientCache::bytesPerPixel() const {
    // We use 4 channels (RGBA)
    return 4 * (mUseFloatTexture ? /* fp16 */ 2 : sizeof(uint8_t));
}

size_t GradientCache::sourceBytesPerPixel() const {
    // We use 4 channels (RGBA) and upload from floats (not half floats)
    return 4 * (mUseFloatTexture ? sizeof(float) : sizeof(uint8_t));
}

void GradientCache::mixBytes(const FloatColor& start, const FloatColor& end,
        float amount, uint8_t*& dst) const {
    float oppAmount = 1.0f - amount;
    float a = start.a * oppAmount + end.a * amount;
    *dst++ = uint8_t(OECF(start.r * oppAmount + end.r * amount) * 255.0f);
    *dst++ = uint8_t(OECF(start.g * oppAmount + end.g * amount) * 255.0f);
    *dst++ = uint8_t(OECF(start.b * oppAmount + end.b * amount) * 255.0f);
    *dst++ = uint8_t(a * 255.0f);
}

void GradientCache::mixFloats(const FloatColor& start, const FloatColor& end,
        float amount, uint8_t*& dst) const {
    float oppAmount = 1.0f - amount;
    float a = start.a * oppAmount + end.a * amount;
    float* d = (float*) dst;
#ifdef ANDROID_ENABLE_LINEAR_BLENDING
    // We want to stay linear
    *d++ = (start.r * oppAmount + end.r * amount);
    *d++ = (start.g * oppAmount + end.g * amount);
    *d++ = (start.b * oppAmount + end.b * amount);
#else
    *d++ = OECF(start.r * oppAmount + end.r * amount);
    *d++ = OECF(start.g * oppAmount + end.g * amount);
    *d++ = OECF(start.b * oppAmount + end.b * amount);
#endif
    *d++ = a;
    dst += 4 * sizeof(float);
}

void GradientCache::generateTexture(uint32_t* colors, float* positions,
        const uint32_t width, const uint32_t height, Texture* texture) {
    const GLsizei rowBytes = width * sourceBytesPerPixel();
    uint8_t pixels[rowBytes * height];

    static ChannelMixer gMixers[] = {
            // colors are stored gamma-encoded
            &android::uirenderer::GradientCache::mixBytes,
            // colors are stored in linear (linear blending on)
            // or gamma-encoded (linear blending off)
            &android::uirenderer::GradientCache::mixFloats,
    };
    ChannelMixer mix = gMixers[mUseFloatTexture];

    FloatColor start;
    start.set(colors[0]);

    FloatColor end;
    end.set(colors[1]);

    int currentPos = 1;
    float startPos = positions[0];
    float distance = positions[1] - startPos;

    uint8_t* dst = pixels;
    for (uint32_t x = 0; x < width; x++) {
        float pos = x / float(width - 1);
        if (pos > positions[currentPos]) {
            start = end;
            startPos = positions[currentPos];

            currentPos++;

            end.set(colors[currentPos]);
            distance = positions[currentPos] - startPos;
        }

        float amount = (pos - startPos) / distance;
        (this->*mix)(start, end, amount, dst);
    }

    memcpy(pixels + rowBytes, pixels, rowBytes);

    if (mUseFloatTexture) {
        texture->upload(GL_RGBA16F, width, height, GL_RGBA, GL_FLOAT, pixels);
    } else {
        GLint internalFormat = mHasLinearBlending ? GL_SRGB8_ALPHA8 : GL_RGBA;
        texture->upload(internalFormat, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    }

    texture->setFilter(GL_LINEAR);
    texture->setWrap(GL_CLAMP_TO_EDGE);
}

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