/*
 * 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_CACHE_H
#define ANDROID_HWUI_TEXTURE_CACHE_H

#include <SkBitmap.h>

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

#include "Debug.h"

namespace android {
namespace uirenderer {

class Texture;

///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////

// Debug
#if DEBUG_TEXTURES
    #define TEXTURE_LOGD(...) ALOGD(__VA_ARGS__)
#else
    #define TEXTURE_LOGD(...)
#endif

///////////////////////////////////////////////////////////////////////////////
// Classes
///////////////////////////////////////////////////////////////////////////////

class AssetAtlas;

/**
 * A simple LRU texture 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 TextureCache : public OnEntryRemoved<uint32_t, Texture*> {
public:
    TextureCache();
    ~TextureCache();

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

    /**
     * Resets all Textures to not be marked as in use
     */
    void resetMarkInUse(void* ownerToken);

    /**
     * Attempts to precache the SkBitmap. Returns true if a Texture was successfully
     * acquired for the bitmap, false otherwise. If a Texture was acquired it is
     * marked as in use.
     */
    bool prefetchAndMarkInUse(void* ownerToken, const SkBitmap* bitmap);

    /**
     * Returns the texture associated with the specified bitmap from either within the cache, or
     * the AssetAtlas. If the texture cannot be found in the cache, a new texture is generated.
     */
    Texture* get(const SkBitmap* bitmap) {
        return get(bitmap, AtlasUsageType::Use);
    }

    /**
     * Returns the texture associated with the specified bitmap. If the texture cannot be found in
     * the cache, a new texture is generated, even if it resides in the AssetAtlas.
     */
    Texture* getAndBypassAtlas(const SkBitmap* bitmap) {
        return get(bitmap, AtlasUsageType::Bypass);
    }

    /**
     * Removes the texture associated with the specified pixelRef. This is meant
     * to be called from threads that are not the EGL context thread.
     */
    ANDROID_API void releaseTexture(uint32_t pixelRefStableID);
    /**
     * Process deferred removals.
     */
    void clearGarbage();

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

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

    /**
     * Partially flushes the cache. The amount of memory freed by a flush
     * is defined by the flush rate.
     */
    void flush();
    /**
     * Indicates the percentage of the cache to retain when a
     * memory trim is requested (see Caches::flush).
     */
    void setFlushRate(float flushRate);

    void setAssetAtlas(AssetAtlas* assetAtlas);

private:
    enum class AtlasUsageType {
        Use,
        Bypass,
    };

    bool canMakeTextureFromBitmap(const SkBitmap* bitmap);

    Texture* get(const SkBitmap* bitmap, AtlasUsageType atlasUsageType);
    Texture* getCachedTexture(const SkBitmap* bitmap, AtlasUsageType atlasUsageType);

    /**
     * Generates the texture from a bitmap into the specified texture structure.
     *
     * @param regenerate If true, the bitmap data is reuploaded into the texture, but
     *        no new texture is generated.
     */
    void generateTexture(const SkBitmap* bitmap, Texture* texture, bool regenerate = false);

    void uploadLoFiTexture(bool resize, const SkBitmap* bitmap, uint32_t width, uint32_t height);
    void uploadToTexture(bool resize, GLenum format, GLsizei stride, GLsizei bpp,
            GLsizei width, GLsizei height, GLenum type, const GLvoid * data);

    LruCache<uint32_t, Texture*> mCache;

    uint32_t mSize;
    uint32_t mMaxSize;
    GLint mMaxTextureSize;

    float mFlushRate;

    bool mDebugEnabled;

    Vector<uint32_t> mGarbage;
    mutable Mutex mLock;

    AssetAtlas* mAssetAtlas;
}; // class TextureCache

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

#endif // ANDROID_HWUI_TEXTURE_CACHE_H
