/*
 * Copyright (C) 2013 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_RENDER_BUFFER_CACHE_H
#define ANDROID_HWUI_RENDER_BUFFER_CACHE_H

#include <GLES2/gl2.h>

#include "RenderBuffer.h"

#include <set>

namespace android {
namespace uirenderer {

class RenderBufferCache {
public:
    RenderBufferCache();
    ~RenderBufferCache();

    /**
     * Returns a buffer with the exact specified dimensions. If no suitable
     * buffer can be found, a new one is created and returned. If creating a
     * new buffer fails, NULL is returned.
     *
     * When a buffer is obtained from the cache, it is removed and the total
     * size of the cache goes down.
     *
     * The returned buffer is always allocated and bound
     * (see RenderBuffer::isAllocated()).
     *
     * @param format The desired render buffer format
     * @param width The desired width of the buffer
     * @param height The desired height of the buffer
     */
    RenderBuffer* get(GLenum format, const uint32_t width, const uint32_t height);

    /**
     * Adds the buffer to the cache. The buffer will not be added if there is
     * not enough space available. Adding a buffer can cause other buffer to
     * be removed from the cache.
     *
     * @param buffer The render buffer to add to the cache
     *
     * @return True if the buffer was added, false otherwise.
     */
    bool put(RenderBuffer* buffer);
    /**
     * Clears the cache. This causes all layers 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:
    struct RenderBufferEntry {
        RenderBufferEntry():
            mBuffer(nullptr), mWidth(0), mHeight(0) {
        }

        RenderBufferEntry(GLenum format, const uint32_t width, const uint32_t height):
            mBuffer(nullptr), mFormat(format), mWidth(width), mHeight(height) {
        }

        explicit RenderBufferEntry(RenderBuffer* buffer):
            mBuffer(buffer), mFormat(buffer->getFormat()),
            mWidth(buffer->getWidth()), mHeight(buffer->getHeight()) {
        }

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

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

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

        bool operator<(const RenderBufferEntry& other) const {
            return RenderBufferEntry::compare(*this, other) < 0;
        }

        RenderBuffer* mBuffer;
        GLenum mFormat;
        uint32_t mWidth;
        uint32_t mHeight;
    }; // struct RenderBufferEntry

    void deleteBuffer(RenderBuffer* buffer);

    std::multiset<RenderBufferEntry> mCache;

    uint32_t mSize;
    uint32_t mMaxSize;
}; // class RenderBufferCache

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

#endif // ANDROID_HWUI_RENDER_BUFFER_CACHE_H
