RenderBufferCache.cpp revision d41c4d8c732095ae99c955b6b82f7306633004b1
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#define LOG_TAG "OpenGLRenderer"
188d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
198d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#include <utils/Log.h>
208d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
218d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#include "Debug.h"
228d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#include "Properties.h"
238d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#include "RenderBufferCache.h"
248d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
258d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guynamespace android {
268d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guynamespace uirenderer {
278d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
288d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy///////////////////////////////////////////////////////////////////////////////
298d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Defines
308d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy///////////////////////////////////////////////////////////////////////////////
318d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
328d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Debug
338d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#if DEBUG_RENDER_BUFFERS
348d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    #define RENDER_BUFFER_LOGD(...) ALOGD(__VA_ARGS__)
358d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#else
368d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    #define RENDER_BUFFER_LOGD(...)
378d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#endif
388d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
398d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy///////////////////////////////////////////////////////////////////////////////
408d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Constructors/destructor
418d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy///////////////////////////////////////////////////////////////////////////////
428d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
438d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain GuyRenderBufferCache::RenderBufferCache(): mSize(0), mMaxSize(MB(DEFAULT_RENDER_BUFFER_CACHE_SIZE)) {
448d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    char property[PROPERTY_VALUE_MAX];
45d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    if (property_get(PROPERTY_RENDER_BUFFER_CACHE_SIZE, property, nullptr) > 0) {
468d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        INIT_LOGD("  Setting render buffer cache size to %sMB", property);
478d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        setMaxSize(MB(atof(property)));
488d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    } else {
498d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        INIT_LOGD("  Using default render buffer cache size of %.2fMB",
508d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                DEFAULT_RENDER_BUFFER_CACHE_SIZE);
518d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    }
528d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
538d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
548d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain GuyRenderBufferCache::~RenderBufferCache() {
558d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    clear();
568d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
588d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy///////////////////////////////////////////////////////////////////////////////
598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Size management
608d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy///////////////////////////////////////////////////////////////////////////////
618d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
628d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyuint32_t RenderBufferCache::getSize() {
638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    return mSize;
648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
658d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
668d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyuint32_t RenderBufferCache::getMaxSize() {
678d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    return mMaxSize;
688d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
698d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
708d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyvoid RenderBufferCache::setMaxSize(uint32_t maxSize) {
718d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    clear();
728d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    mMaxSize = maxSize;
738d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
748d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
758d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy///////////////////////////////////////////////////////////////////////////////
768d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Caching
778d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy///////////////////////////////////////////////////////////////////////////////
788d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
798d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyint RenderBufferCache::RenderBufferEntry::compare(
808d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        const RenderBufferCache::RenderBufferEntry& lhs,
818d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        const RenderBufferCache::RenderBufferEntry& rhs) {
828d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    int deltaInt = int(lhs.mWidth) - int(rhs.mWidth);
838d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    if (deltaInt != 0) return deltaInt;
848d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
858d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    deltaInt = int(lhs.mHeight) - int(rhs.mHeight);
868d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    if (deltaInt != 0) return deltaInt;
878d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
888d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    return int(lhs.mFormat) - int(rhs.mFormat);
898d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
908d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
918d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyvoid RenderBufferCache::deleteBuffer(RenderBuffer* buffer) {
928d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    if (buffer) {
938d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d)",
948d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                RenderBuffer::formatName(buffer->getFormat()),
958d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                buffer->getWidth(), buffer->getHeight());
968d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
978d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        mSize -= buffer->getSize();
988d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        delete buffer;
998d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    }
1008d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
1018d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1028d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyvoid RenderBufferCache::clear() {
1038d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    size_t count = mCache.size();
1048d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    for (size_t i = 0; i < count; i++) {
1058d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        deleteBuffer(mCache.itemAt(i).mBuffer);
1068d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    }
1078d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    mCache.clear();
1088d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
1098d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1108d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain GuyRenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) {
111d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    RenderBuffer* buffer = nullptr;
1128d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1138d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    RenderBufferEntry entry(format, width, height);
1148d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    ssize_t index = mCache.indexOf(entry);
1158d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1168d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    if (index >= 0) {
1178d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        entry = mCache.itemAt(index);
1188d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        mCache.removeAt(index);
1198d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1208d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        buffer = entry.mBuffer;
1218d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        mSize -= buffer->getSize();
1228d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1238d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        RENDER_BUFFER_LOGD("Found %s render buffer (%dx%d)",
1248d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                RenderBuffer::formatName(format), width, height);
1258d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    } else {
1268d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        buffer = new RenderBuffer(format, width, height);
1278d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1288d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        RENDER_BUFFER_LOGD("Created new %s render buffer (%dx%d)",
1298d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                RenderBuffer::formatName(format), width, height);
1308d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    }
1318d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1328d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    buffer->bind();
1338d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    buffer->allocate();
1348d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1358d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    return buffer;
1368d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
1378d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1388d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guybool RenderBufferCache::put(RenderBuffer* buffer) {
1398d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    if (!buffer) return false;
1408d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1418d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    const uint32_t size = buffer->getSize();
1428d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    if (size < mMaxSize) {
1438d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        while (mSize + size > mMaxSize) {
1448d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            size_t position = 0;
1458d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1468d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            RenderBuffer* victim = mCache.itemAt(position).mBuffer;
1478d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            deleteBuffer(victim);
1488d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            mCache.removeAt(position);
1498d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        }
1508d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1518d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        RenderBufferEntry entry(buffer);
1528d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1538d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        mCache.add(entry);
1548d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        mSize += size;
1558d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1568d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)",
1578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                RenderBuffer::formatName(buffer->getFormat()),
1588d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                buffer->getWidth(), buffer->getHeight());
1598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1608d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        return true;
1618d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    }
1628d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    return false;
1638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}
1648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1658d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}; // namespace uirenderer
1668d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}; // namespace android
167