RenderBufferCache.cpp revision 8dc02f99d09130ace2ee738c2e689db1b3f33181
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" 208dc02f99d09130ace2ee738c2e689db1b3f33181John Reck#include "DeviceInfo.h" 218d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 226b50780363d3bb8db600c770183fa07677509ae8John Reck#include <utils/Log.h> 236b50780363d3bb8db600c770183fa07677509ae8John Reck 246b50780363d3bb8db600c770183fa07677509ae8John Reck#include <cstdlib> 256b50780363d3bb8db600c770183fa07677509ae8John Reck 268d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guynamespace android { 278d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guynamespace uirenderer { 288d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 298d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 308d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Defines 318d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 328d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 338d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Debug 348d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#if DEBUG_RENDER_BUFFERS 358d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy #define RENDER_BUFFER_LOGD(...) ALOGD(__VA_ARGS__) 368d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#else 378d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy #define RENDER_BUFFER_LOGD(...) 388d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#endif 398d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 408dc02f99d09130ace2ee738c2e689db1b3f33181John Reckstatic uint32_t calculateRboCacheSize() { 418dc02f99d09130ace2ee738c2e689db1b3f33181John Reck // TODO: Do we need to use extensions().has4BitStencil() here? 428dc02f99d09130ace2ee738c2e689db1b3f33181John Reck // The tuning guide recommends it, but all real devices are configured 438dc02f99d09130ace2ee738c2e689db1b3f33181John Reck // with a larger cache than necessary by 4x, so keep the 2x for now regardless 448dc02f99d09130ace2ee738c2e689db1b3f33181John Reck return DeviceInfo::multiplyByResolution(2); 458dc02f99d09130ace2ee738c2e689db1b3f33181John Reck} 468dc02f99d09130ace2ee738c2e689db1b3f33181John Reck 478d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 488d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Constructors/destructor 498d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 508d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 5148a8f431fa52ae2ee25ffba9d20676f03bb710ffChris CraikRenderBufferCache::RenderBufferCache() 5248a8f431fa52ae2ee25ffba9d20676f03bb710ffChris Craik : mSize(0) 538dc02f99d09130ace2ee738c2e689db1b3f33181John Reck , mMaxSize(calculateRboCacheSize()) {} 548d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 558d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain GuyRenderBufferCache::~RenderBufferCache() { 568d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy clear(); 578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 588d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 608d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Size management 618d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 628d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyuint32_t RenderBufferCache::getSize() { 648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return mSize; 658d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 668d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 678d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyuint32_t RenderBufferCache::getMaxSize() { 688d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return mMaxSize; 698d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 708d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 718d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 728d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Caching 738d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 748d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 758d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyint RenderBufferCache::RenderBufferEntry::compare( 768d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy const RenderBufferCache::RenderBufferEntry& lhs, 778d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy const RenderBufferCache::RenderBufferEntry& rhs) { 788d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy int deltaInt = int(lhs.mWidth) - int(rhs.mWidth); 798d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (deltaInt != 0) return deltaInt; 808d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 818d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy deltaInt = int(lhs.mHeight) - int(rhs.mHeight); 828d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (deltaInt != 0) return deltaInt; 838d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 848d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return int(lhs.mFormat) - int(rhs.mFormat); 858d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 868d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 878d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyvoid RenderBufferCache::deleteBuffer(RenderBuffer* buffer) { 888d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (buffer) { 898d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d)", 908d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBuffer::formatName(buffer->getFormat()), 918d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer->getWidth(), buffer->getHeight()); 928d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 938d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mSize -= buffer->getSize(); 948d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy delete buffer; 958d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 968d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 978d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 988d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyvoid RenderBufferCache::clear() { 99bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck for (auto entry : mCache) { 100bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck deleteBuffer(entry.mBuffer); 1018d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1028d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mCache.clear(); 1038d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1048d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1058d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain GuyRenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) { 106d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik RenderBuffer* buffer = nullptr; 1078d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1088d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBufferEntry entry(format, width, height); 109bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck auto iter = mCache.find(entry); 1108d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 111bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck if (iter != mCache.end()) { 112bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck entry = *iter; 113bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck mCache.erase(iter); 1148d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1158d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer = entry.mBuffer; 1168d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mSize -= buffer->getSize(); 1178d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1188d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RENDER_BUFFER_LOGD("Found %s render buffer (%dx%d)", 1198d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBuffer::formatName(format), width, height); 1208d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } else { 1218d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer = new RenderBuffer(format, width, height); 1228d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1238d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RENDER_BUFFER_LOGD("Created new %s render buffer (%dx%d)", 1248d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBuffer::formatName(format), width, height); 1258d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1268d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1278d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer->bind(); 1288d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer->allocate(); 1298d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1308d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return buffer; 1318d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1328d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1338d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guybool RenderBufferCache::put(RenderBuffer* buffer) { 1348d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (!buffer) return false; 1358d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1368d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy const uint32_t size = buffer->getSize(); 1378d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (size < mMaxSize) { 1388d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy while (mSize + size > mMaxSize) { 139bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck RenderBuffer* victim = mCache.begin()->mBuffer; 1408d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy deleteBuffer(victim); 141bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck mCache.erase(mCache.begin()); 1428d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1438d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1448d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBufferEntry entry(buffer); 1458d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 146bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck mCache.insert(entry); 1478d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mSize += size; 1488d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1498d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)", 1508d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBuffer::formatName(buffer->getFormat()), 1518d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer->getWidth(), buffer->getHeight()); 1528d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1538d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return true; 154e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung } else { 155e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d) Size=%d, MaxSize=%d", 156e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung RenderBuffer::formatName(buffer->getFormat()), 157e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung buffer->getWidth(), buffer->getHeight(), size, mMaxSize); 158e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung delete buffer; 1598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1608d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return false; 1618d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1628d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}; // namespace uirenderer 1648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy}; // namespace android 165