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