/*
 * 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 "LayerCache.h"

#include "Caches.h"
#include "Properties.h"

#include <utils/Log.h>

#include <GLES2/gl2.h>

namespace android {
namespace uirenderer {

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

LayerCache::LayerCache()
        : mSize(0)
        , mMaxSize(Properties::layerPoolSize) {}

LayerCache::~LayerCache() {
    clear();
}

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

size_t LayerCache::getCount() {
    return mCache.size();
}

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

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

void LayerCache::setMaxSize(uint32_t maxSize) {
    clear();
    mMaxSize = maxSize;
}

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

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

    return int(lhs.mHeight) - int(rhs.mHeight);
}

void LayerCache::deleteLayer(Layer* layer) {
    if (layer) {
        LAYER_LOGD("Destroying layer %dx%d, fbo %d", layer->getWidth(), layer->getHeight(),
                layer->getFbo());
        mSize -= layer->getWidth() * layer->getHeight() * 4;
        layer->state = Layer::State::DeletedFromCache;
        layer->decStrong(nullptr);
    }
}

void LayerCache::clear() {
    for (auto entry : mCache) {
        deleteLayer(entry.mLayer);
    }
    mCache.clear();
}

Layer* LayerCache::get(RenderState& renderState, const uint32_t width, const uint32_t height) {
    Layer* layer = nullptr;

    LayerEntry entry(width, height);
    auto iter = mCache.find(entry);

    if (iter != mCache.end()) {
        entry = *iter;
        mCache.erase(iter);

        layer = entry.mLayer;
        layer->state = Layer::State::RemovedFromCache;
        mSize -= layer->getWidth() * layer->getHeight() * 4;

        LAYER_LOGD("Reusing layer %dx%d", layer->getWidth(), layer->getHeight());
    } else {
        LAYER_LOGD("Creating new layer %dx%d", entry.mWidth, entry.mHeight);

        layer = new Layer(Layer::Type::DisplayList, renderState, entry.mWidth, entry.mHeight);
        layer->setBlend(true);
        layer->generateTexture();
        layer->bindTexture();
        layer->setFilter(GL_NEAREST);
        layer->setWrap(GL_CLAMP_TO_EDGE, false);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

#if DEBUG_LAYERS
        dump();
#endif
    }

    return layer;
}

void LayerCache::dump() {
    for (auto entry : mCache) {
        ALOGD("  Layer size %dx%d", entry.mWidth, entry.mHeight);
    }
}

bool LayerCache::put(Layer* layer) {
    if (!layer->isCacheable()) return false;

    const uint32_t size = layer->getWidth() * layer->getHeight() * 4;
    // Don't even try to cache a layer that's bigger than the cache
    if (size < mMaxSize) {
        // TODO: Use an LRU
        while (mSize + size > mMaxSize) {
            Layer* victim = mCache.begin()->mLayer;
            deleteLayer(victim);
            mCache.erase(mCache.begin());

            LAYER_LOGD("  Deleting layer %.2fx%.2f", victim->layer.getWidth(),
                    victim->layer.getHeight());
        }

        layer->cancelDefer();

        LayerEntry entry(layer);

        mCache.insert(entry);
        mSize += size;

        layer->state = Layer::State::InCache;
        return true;
    }

    layer->state = Layer::State::FailedToCache;
    return false;
}

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