RenderBufferCache.cpp revision 6b50780363d3bb8db600c770183fa07677509ae8
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#include "Debug.h" 188d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#include "Properties.h" 198d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#include "RenderBufferCache.h" 208d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 216b50780363d3bb8db600c770183fa07677509ae8John Reck#include <utils/Log.h> 226b50780363d3bb8db600c770183fa07677509ae8John Reck 236b50780363d3bb8db600c770183fa07677509ae8John Reck#include <cstdlib> 246b50780363d3bb8db600c770183fa07677509ae8John Reck 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() { 103bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck for (auto entry : mCache) { 104bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck deleteBuffer(entry.mBuffer); 1058d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1068d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mCache.clear(); 1078d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1088d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1098d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain GuyRenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) { 110d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik RenderBuffer* buffer = nullptr; 1118d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1128d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBufferEntry entry(format, width, height); 113bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck auto iter = mCache.find(entry); 1148d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 115bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck if (iter != mCache.end()) { 116bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck entry = *iter; 117bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck mCache.erase(iter); 1188d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1198d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer = entry.mBuffer; 1208d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mSize -= buffer->getSize(); 1218d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1228d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RENDER_BUFFER_LOGD("Found %s render buffer (%dx%d)", 1238d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBuffer::formatName(format), width, height); 1248d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } else { 1258d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer = new RenderBuffer(format, width, height); 1268d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1278d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RENDER_BUFFER_LOGD("Created new %s render buffer (%dx%d)", 1288d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBuffer::formatName(format), width, height); 1298d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1308d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1318d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer->bind(); 1328d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer->allocate(); 1338d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1348d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return buffer; 1358d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1368d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1378d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guybool RenderBufferCache::put(RenderBuffer* buffer) { 1388d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (!buffer) return false; 1398d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1408d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy const uint32_t size = buffer->getSize(); 1418d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (size < mMaxSize) { 1428d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy while (mSize + size > mMaxSize) { 143bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck RenderBuffer* victim = mCache.begin()->mBuffer; 1448d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy deleteBuffer(victim); 145bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck mCache.erase(mCache.begin()); 1468d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1478d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1488d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBufferEntry entry(buffer); 1498d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 150bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck mCache.insert(entry); 1518d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mSize += size; 1528d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1538d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)", 1548d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBuffer::formatName(buffer->getFormat()), 1558d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer->getWidth(), buffer->getHeight()); 1568d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return true; 158e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung } else { 159e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d) Size=%d, MaxSize=%d", 160e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung RenderBuffer::formatName(buffer->getFormat()), 161e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung buffer->getWidth(), buffer->getHeight(), size, mMaxSize); 162e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung delete buffer; 1638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return false; 1658d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1668d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1678d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}; // namespace uirenderer 1688d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}; // namespace android 169