18d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/*
28d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy * Copyright (C) 2013 The Android Open Source Project
38d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy *
48d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
58d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy * you may not use this file except in compliance with the License.
68d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy * You may obtain a copy of the License at
78d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy *
88d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
98d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy *
108d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy * Unless required by applicable law or agreed to in writing, software
118d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
128d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy * See the License for the specific language governing permissions and
148d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy * limitations under the License.
158d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy */
168d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
178d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#ifndef ANDROID_HWUI_RENDER_BUFFER_CACHE_H
188d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#define ANDROID_HWUI_RENDER_BUFFER_CACHE_H
198d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
208d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#include <GLES2/gl2.h>
218d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
228d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#include "RenderBuffer.h"
23bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck
24bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck#include <set>
258d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
268d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guynamespace android {
278d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guynamespace uirenderer {
288d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
298d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyclass RenderBufferCache {
308d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guypublic:
318d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    RenderBufferCache();
328d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    ~RenderBufferCache();
338d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
348d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    /**
358d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * Returns a buffer with the exact specified dimensions. If no suitable
368d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * buffer can be found, a new one is created and returned. If creating a
378d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * new buffer fails, NULL is returned.
388d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     *
398d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * When a buffer is obtained from the cache, it is removed and the total
408d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * size of the cache goes down.
418d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     *
428d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * The returned buffer is always allocated and bound
438d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * (see RenderBuffer::isAllocated()).
448d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     *
458d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * @param format The desired render buffer format
468d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * @param width The desired width of the buffer
478d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * @param height The desired height of the buffer
488d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     */
498d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    RenderBuffer* get(GLenum format, const uint32_t width, const uint32_t height);
508d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
518d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    /**
528d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * Adds the buffer to the cache. The buffer will not be added if there is
538d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * not enough space available. Adding a buffer can cause other buffer to
548d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * be removed from the cache.
558d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     *
568d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * @param buffer The render buffer to add to the cache
578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     *
588d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * @return True if the buffer was added, false otherwise.
598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     */
608d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    bool put(RenderBuffer* buffer);
618d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    /**
628d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * Clears the cache. This causes all layers to be deleted.
638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     */
648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    void clear();
658d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
668d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    /**
678d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * Returns the maximum size of the cache in bytes.
688d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     */
698d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    uint32_t getMaxSize();
708d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    /**
718d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * Returns the current size of the cache in bytes.
728d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     */
738d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    uint32_t getSize();
748d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
758d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyprivate:
768d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    struct RenderBufferEntry {
778d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        RenderBufferEntry():
78e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik            mBuffer(nullptr), mWidth(0), mHeight(0) {
798d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        }
808d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
818d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        RenderBufferEntry(GLenum format, const uint32_t width, const uint32_t height):
82e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik            mBuffer(nullptr), mFormat(format), mWidth(width), mHeight(height) {
838d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        }
848d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
858d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        RenderBufferEntry(RenderBuffer* buffer):
868d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            mBuffer(buffer), mFormat(buffer->getFormat()),
878d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            mWidth(buffer->getWidth()), mHeight(buffer->getHeight()) {
888d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        }
898d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
908d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        static int compare(const RenderBufferEntry& lhs, const RenderBufferEntry& rhs);
918d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
928d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        bool operator==(const RenderBufferEntry& other) const {
938d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            return compare(*this, other) == 0;
948d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        }
958d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
968d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        bool operator!=(const RenderBufferEntry& other) const {
978d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            return compare(*this, other) != 0;
988d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        }
998d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
100bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck        bool operator<(const RenderBufferEntry& other) const {
101bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck            return RenderBufferEntry::compare(*this, other) < 0;
1028d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        }
1038d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1048d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        RenderBuffer* mBuffer;
1058d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        GLenum mFormat;
1068d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        uint32_t mWidth;
1078d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        uint32_t mHeight;
1088d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    }; // struct RenderBufferEntry
1098d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1108d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    void deleteBuffer(RenderBuffer* buffer);
1118d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
112bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck    std::multiset<RenderBufferEntry> mCache;
1138d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1148d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    uint32_t mSize;
1158d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    uint32_t mMaxSize;
1168d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}; // class RenderBufferCache
1178d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1188d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}; // namespace uirenderer
1198d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}; // namespace android
1208d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1218d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#endif // ANDROID_HWUI_RENDER_BUFFER_CACHE_H
122