/*
 * Copyright (C) 2015 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_OFFSCREEN_BUFFER_POOL_H
#define ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H

#include <GpuMemoryTracker.h>
#include "Caches.h"
#include "Texture.h"
#include "utils/Macros.h"
#include <ui/Region.h>

#include <set>

namespace android {
namespace uirenderer {

class RenderState;

/**
 * Lightweight alternative to Layer. Owns the persistent state of an offscreen render target, and
 * encompasses enough information to draw it back on screen (minus paint properties, which are held
 * by LayerOp).
 *
 * Has two distinct sizes - viewportWidth/viewportHeight describe content area,
 * texture.width/.height are actual allocated texture size. Texture will tend to be larger than the
 * viewport bounds, since textures are always allocated with width / height as a multiple of 64, for
 * the purpose of improving reuse.
 */
class OffscreenBuffer : GpuMemoryTracker {
public:
    OffscreenBuffer(RenderState& renderState, Caches& caches,
            uint32_t viewportWidth, uint32_t viewportHeight);
    ~OffscreenBuffer();

    Rect getTextureCoordinates();

    void dirty(Rect dirtyArea);

    // must be called prior to rendering, to construct/update vertex buffer
    void updateMeshFromRegion();

    // Set by RenderNode for HW layers, TODO for clipped saveLayers
    void setWindowTransform(const Matrix4& transform) {
        inverseTransformInWindow.loadInverse(transform);
    }

    static uint32_t computeIdealDimension(uint32_t dimension);

    uint32_t getSizeInBytes() { return texture.objectSize(); }

    RenderState& renderState;

    uint32_t viewportWidth;
    uint32_t viewportHeight;
    Texture texture;

    // Portion of layer that has been drawn to. Used to minimize drawing area when
    // drawing back to screen / parent FBO.
    Region region;

    Matrix4 inverseTransformInWindow;

    // vbo / size of mesh
    GLsizei elementCount = 0;
    GLuint vbo = 0;
};

/**
 * Pool of OffscreenBuffers allocated, but not currently in use.
 */
class OffscreenBufferPool {
public:
    OffscreenBufferPool();
    ~OffscreenBufferPool();

    WARN_UNUSED_RESULT OffscreenBuffer* get(RenderState& renderState,
            const uint32_t width, const uint32_t height);

    WARN_UNUSED_RESULT OffscreenBuffer* resize(OffscreenBuffer* layer,
            const uint32_t width, const uint32_t height);

    void putOrDelete(OffscreenBuffer* layer);

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

    /**
     * Returns the maximum size of the pool in bytes.
     */
    uint32_t getMaxSize() { return mMaxSize; }

    /**
     * Returns the current size of the pool in bytes.
     */
    uint32_t getSize() { return mSize; }

    size_t getCount() { return mPool.size(); }

    /**
     * Prints out the content of the pool.
     */
    void dump();
private:
    struct Entry {
        Entry() {}

        Entry(const uint32_t layerWidth, const uint32_t layerHeight)
                : width(OffscreenBuffer::computeIdealDimension(layerWidth))
                , height(OffscreenBuffer::computeIdealDimension(layerHeight)) {}

        Entry(OffscreenBuffer* layer)
                : layer(layer)
                , width(layer->texture.width())
                , height(layer->texture.height()) {
        }

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

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

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

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

        OffscreenBuffer* layer = nullptr;
        uint32_t width = 0;
        uint32_t height = 0;
    }; // struct Entry

    std::multiset<Entry> mPool;

    uint32_t mSize = 0;
    uint32_t mMaxSize;
}; // class OffscreenBufferCache

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

#endif // ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H
