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 "RenderBufferCache.h" 181bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#include "Debug.h" 198dc02f99d09130ace2ee738c2e689db1b3f33181John Reck#include "DeviceInfo.h" 201bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#include "Properties.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 351bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#define RENDER_BUFFER_LOGD(...) ALOGD(__VA_ARGS__) 368d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy#else 371bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#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 511bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John ReckRenderBufferCache::RenderBufferCache() : mSize(0), mMaxSize(calculateRboCacheSize()) {} 528d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 538d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain GuyRenderBufferCache::~RenderBufferCache() { 548d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy clear(); 558d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 568d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 588d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Size management 598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 608d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 618d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyuint32_t RenderBufferCache::getSize() { 628d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return mSize; 638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 658d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyuint32_t RenderBufferCache::getMaxSize() { 668d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return mMaxSize; 678d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 688d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 698d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 708d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy// Caching 718d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy/////////////////////////////////////////////////////////////////////////////// 728d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 731bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reckint RenderBufferCache::RenderBufferEntry::compare(const RenderBufferCache::RenderBufferEntry& lhs, 741bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const RenderBufferCache::RenderBufferEntry& rhs) { 758d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy int deltaInt = int(lhs.mWidth) - int(rhs.mWidth); 768d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (deltaInt != 0) return deltaInt; 778d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 788d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy deltaInt = int(lhs.mHeight) - int(rhs.mHeight); 798d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (deltaInt != 0) return deltaInt; 808d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 818d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return int(lhs.mFormat) - int(rhs.mFormat); 828d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 838d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 848d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyvoid RenderBufferCache::deleteBuffer(RenderBuffer* buffer) { 858d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (buffer) { 868d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d)", 871bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck RenderBuffer::formatName(buffer->getFormat()), buffer->getWidth(), 881bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck buffer->getHeight()); 898d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 908d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mSize -= buffer->getSize(); 918d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy delete buffer; 928d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 938d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 948d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 958d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guyvoid RenderBufferCache::clear() { 96bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck for (auto entry : mCache) { 97bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck deleteBuffer(entry.mBuffer); 988d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 998d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mCache.clear(); 1008d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1018d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1028d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain GuyRenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) { 103d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik RenderBuffer* buffer = nullptr; 1048d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1058d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBufferEntry entry(format, width, height); 106bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck auto iter = mCache.find(entry); 1078d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 108bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck if (iter != mCache.end()) { 109bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck entry = *iter; 110bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck mCache.erase(iter); 1118d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1128d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer = entry.mBuffer; 1138d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mSize -= buffer->getSize(); 1148d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1151bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck RENDER_BUFFER_LOGD("Found %s render buffer (%dx%d)", RenderBuffer::formatName(format), 1161bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck width, height); 1178d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } else { 1188d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer = new RenderBuffer(format, width, height); 1198d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1201bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck RENDER_BUFFER_LOGD("Created new %s render buffer (%dx%d)", RenderBuffer::formatName(format), 1211bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck width, height); 1228d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1238d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1248d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer->bind(); 1258d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy buffer->allocate(); 1268d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1278d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return buffer; 1288d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1298d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1308d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guybool RenderBufferCache::put(RenderBuffer* buffer) { 1318d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (!buffer) return false; 1328d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1338d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy const uint32_t size = buffer->getSize(); 1348d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy if (size < mMaxSize) { 1358d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy while (mSize + size > mMaxSize) { 136bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck RenderBuffer* victim = mCache.begin()->mBuffer; 1378d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy deleteBuffer(victim); 138bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck mCache.erase(mCache.begin()); 1398d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1408d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1418d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RenderBufferEntry entry(buffer); 1428d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 143bef837dc57b47fd7fcc17c86d741cf77eac4487bJohn Reck mCache.insert(entry); 1448d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy mSize += size; 1458d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1468d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)", 1471bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck RenderBuffer::formatName(buffer->getFormat()), buffer->getWidth(), 1481bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck buffer->getHeight()); 1498d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1508d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return true; 151e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung } else { 152e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d) Size=%d, MaxSize=%d", 1531bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck RenderBuffer::formatName(buffer->getFormat()), buffer->getWidth(), 1541bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck buffer->getHeight(), size, mMaxSize); 155e11f3ab000ec8d71e816aea7f266a3ceafebfd56Samsung delete buffer; 1568d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return false; 1588d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy 1601bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace uirenderer 1611bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace android 162